Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 2,322 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Batch Update Rem... | 20638067 | 5 mins ago | IN | 0 ETH | 0.00003143 | ||||
Batch Update Rem... | 20637473 | 2 hrs ago | IN | 0 ETH | 0.00003706 | ||||
Batch Update Rem... | 20637473 | 2 hrs ago | IN | 0 ETH | 0.00003705 | ||||
Batch Update Rem... | 20637177 | 3 hrs ago | IN | 0 ETH | 0.00005268 | ||||
Batch Update Rem... | 20636878 | 4 hrs ago | IN | 0 ETH | 0.00004839 | ||||
Batch Update Rem... | 20636581 | 5 hrs ago | IN | 0 ETH | 0.00013427 | ||||
Batch Update Rem... | 20636285 | 6 hrs ago | IN | 0 ETH | 0.0000954 | ||||
Batch Update Rem... | 20636284 | 6 hrs ago | IN | 0 ETH | 0.00009691 | ||||
Batch Update Rem... | 20636283 | 6 hrs ago | IN | 0 ETH | 0.00009514 | ||||
Batch Update Rem... | 20635986 | 7 hrs ago | IN | 0 ETH | 0.0001268 | ||||
Batch Update Rem... | 20635986 | 7 hrs ago | IN | 0 ETH | 0.0001249 | ||||
Batch Update Rem... | 20635685 | 8 hrs ago | IN | 0 ETH | 0.00010134 | ||||
Batch Update Rem... | 20634497 | 12 hrs ago | IN | 0 ETH | 0.00016833 | ||||
Batch Update Rem... | 20634492 | 12 hrs ago | IN | 0 ETH | 0.00018372 | ||||
Batch Update Rem... | 20633302 | 16 hrs ago | IN | 0 ETH | 0.0000441 | ||||
Batch Update Rem... | 20633003 | 17 hrs ago | IN | 0 ETH | 0.00004262 | ||||
Batch Update Rem... | 20632704 | 18 hrs ago | IN | 0 ETH | 0.00003948 | ||||
Batch Update Rem... | 20632704 | 18 hrs ago | IN | 0 ETH | 0.00003831 | ||||
Batch Update Rem... | 20632407 | 19 hrs ago | IN | 0 ETH | 0.00003544 | ||||
Batch Update Rem... | 20632111 | 20 hrs ago | IN | 0 ETH | 0.00003392 | ||||
Batch Update Rem... | 20632111 | 20 hrs ago | IN | 0 ETH | 0.0000339 | ||||
Batch Update Rem... | 20631816 | 21 hrs ago | IN | 0 ETH | 0.00003383 | ||||
Batch Update Rem... | 20631814 | 21 hrs ago | IN | 0 ETH | 0.00003669 | ||||
Batch Update Rem... | 20631813 | 21 hrs ago | IN | 0 ETH | 0.00003779 | ||||
Batch Update Rem... | 20631518 | 22 hrs ago | IN | 0 ETH | 0.00003326 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19790883 | 118 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PaymentHelper
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { IPaymentHelperV2 as IPaymentHelper } from "src/interfaces/IPaymentHelperV2.sol"; import { ISuperRBAC } from "src/interfaces/ISuperRBAC.sol"; import { ISuperRegistry } from "src/interfaces/ISuperRegistry.sol"; import { ISuperformFactory } from "src/interfaces/ISuperformFactory.sol"; import { IBaseStateRegistry } from "src/interfaces/IBaseStateRegistry.sol"; import { IAmbImplementation } from "src/interfaces/IAmbImplementation.sol"; import { Error } from "src/libraries/Error.sol"; import { DataLib } from "src/libraries/DataLib.sol"; import { ProofLib } from "src/libraries/ProofLib.sol"; import { ArrayCastLib } from "src/libraries/ArrayCastLib.sol"; import { SingleDirectSingleVaultStateReq, SingleXChainSingleVaultStateReq, SingleDirectMultiVaultStateReq, SingleXChainMultiVaultStateReq, MultiDstSingleVaultStateReq, MultiDstMultiVaultStateReq, LiqRequest, AMBMessage, MultiVaultSFData, SingleVaultSFData, AMBExtraData, InitMultiVaultData, InitSingleVaultData, ReturnMultiData, ReturnSingleData } from "src/types/DataTypes.sol"; import { AggregatorV3Interface } from "src/vendor/chainlink/AggregatorV3Interface.sol"; /// @dev interface to read public variable from state registry interface ReadOnlyBaseRegistry is IBaseStateRegistry { function payloadsCount() external view returns (uint256); } /// @title PaymentHelper /// @dev Helps estimate the cost for the entire transaction lifecycle /// @author ZeroPoint Labs contract PaymentHelper is IPaymentHelper { using DataLib for uint256; using ArrayCastLib for LiqRequest; using ArrayCastLib for bool; using ProofLib for bytes; using ProofLib for AMBMessage; ////////////////////////////////////////////////////////////// // CONSTANTS // ////////////////////////////////////////////////////////////// uint256 private constant PROOF_LENGTH = 160; uint8 private constant SUPPORTED_FEED_PRECISION = 8; uint32 private constant TIMELOCK_FORM_ID = 2; uint256 private constant MAX_UINT256 = type(uint256).max; ISuperRegistry public immutable superRegistry; uint64 public immutable CHAIN_ID; ////////////////////////////////////////////////////////////// // STATE VARIABLES // ////////////////////////////////////////////////////////////// /// @dev xchain params mapping(uint64 chainId => AggregatorV3Interface) public nativeFeedOracle; mapping(uint64 chainId => AggregatorV3Interface) public gasPriceOracle; mapping(uint64 chainId => uint256 gasForSwap) public swapGasUsed; mapping(uint64 chainId => uint256 gasForUpdateDeposit) public updateDepositGasUsed; mapping(uint64 chainId => uint256 gasForUpdateWithdraw) public updateWithdrawGasUsed; mapping(uint64 chainId => uint256 gasForDeposit) public depositGasUsed; mapping(uint64 chainId => uint256 gasForWithdraw) public withdrawGasUsed; mapping(uint64 chainId => uint256 defaultNativePrice) public nativePrice; mapping(uint64 chainId => uint256 defaultGasPrice) public gasPrice; mapping(uint64 chainId => uint256 gasPerByte) public gasPerByte; mapping(uint64 chainId => uint256 gasForAck) public ackGasCost; mapping(uint64 chainId => uint256 gasForTimelock) public timelockCost; mapping(uint64 chainId => uint256 gasForEmergency) public emergencyCost; /// @dev register transmuter params bytes public extraDataForTransmuter; ////////////////////////////////////////////////////////////// // STRUCTS // ////////////////////////////////////////////////////////////// struct EstimateAckCostVars { uint256 currPayloadId; uint256 payloadHeader; uint8 callbackType; bytes payloadBody; uint8[] ackAmbIds; uint8 isMulti; uint64 srcChainId; bytes message; } struct LocalEstimateVars { uint256 len; uint256 superformIdsLen; uint256 totalGas; uint256 ambFees; bool paused; } struct CalculateAmountsReq { uint256 i; uint64[] dstChainIds; uint8[] ambIds; MultiVaultSFData[] superformsData; SingleVaultSFData[] superformData; ISuperformFactory factory; bool isDeposit; } ////////////////////////////////////////////////////////////// // MODIFIERS // ////////////////////////////////////////////////////////////// modifier onlyProtocolAdmin() { if (!ISuperRBAC(_getAddress(keccak256("SUPER_RBAC"))).hasProtocolAdminRole(msg.sender)) { revert Error.NOT_PROTOCOL_ADMIN(); } _; } modifier onlyPaymentAdmin() { if ( !ISuperRBAC(superRegistry.getAddress(keccak256("SUPER_RBAC"))).hasRole( keccak256("PAYMENT_ADMIN_ROLE"), msg.sender ) ) { revert Error.NOT_PAYMENT_ADMIN(); } _; } ////////////////////////////////////////////////////////////// // CONSTRUCTOR // ////////////////////////////////////////////////////////////// constructor(address superRegistry_) { if (superRegistry_ == address(0)) { revert Error.ZERO_ADDRESS(); } if (block.chainid > type(uint64).max) { revert Error.BLOCK_CHAIN_ID_OUT_OF_BOUNDS(); } CHAIN_ID = uint64(block.chainid); superRegistry = ISuperRegistry(superRegistry_); } ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @inheritdoc IPaymentHelper function calculateAMBData( uint64 dstChainId_, uint8[] calldata ambIds_, bytes memory message_ ) external view override returns (uint256 totalFees, bytes memory extraData) { (uint256[] memory gasPerAMB, bytes[] memory extraDataPerAMB, uint256 fees) = _estimateAMBFeesReturnExtraData(dstChainId_, ambIds_, message_); extraData = abi.encode(AMBExtraData(gasPerAMB, extraDataPerAMB)); totalFees = fees; } /// @inheritdoc IPaymentHelper function getRegisterTransmuterAMBData() external view override returns (bytes memory) { return extraDataForTransmuter; } /// @inheritdoc IPaymentHelper function estimateMultiDstMultiVault( MultiDstMultiVaultStateReq calldata req_, bool isDeposit_ ) external view override returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount) { uint256 len = req_.dstChainIds.length; uint256 liqAmountIndex; uint256 srcAmountIndex; uint256 dstAmountIndex; ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY"))); SingleVaultSFData[] memory temp; for (uint256 i; i < len; ++i) { (liqAmountIndex, srcAmountIndex, dstAmountIndex) = _calculateAmounts( CalculateAmountsReq(i, req_.dstChainIds, req_.ambIds[i], req_.superformsData, temp, factory, isDeposit_) ); liqAmount += liqAmountIndex; srcAmount += srcAmountIndex; dstAmount += dstAmountIndex; } totalAmount = srcAmount + dstAmount + liqAmount; } /// @inheritdoc IPaymentHelper function estimateMultiDstSingleVault( MultiDstSingleVaultStateReq calldata req_, bool isDeposit_ ) external view override returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount) { uint256 len = req_.dstChainIds.length; uint256 liqAmountIndex; uint256 srcAmountIndex; uint256 dstAmountIndex; ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY"))); MultiVaultSFData[] memory temp; for (uint256 i; i < len; ++i) { (liqAmountIndex, srcAmountIndex, dstAmountIndex) = _calculateAmounts( CalculateAmountsReq(i, req_.dstChainIds, req_.ambIds[i], temp, req_.superformsData, factory, isDeposit_) ); liqAmount += liqAmountIndex; srcAmount += srcAmountIndex; dstAmount += dstAmountIndex; } totalAmount = srcAmount + dstAmount + liqAmount; } /// @inheritdoc IPaymentHelper function estimateSingleXChainMultiVault( SingleXChainMultiVaultStateReq calldata req_, bool isDeposit_ ) external view override returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount) { ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY"))); uint64[] memory dstChainIds = new uint64[](1); dstChainIds[0] = req_.dstChainId; SingleVaultSFData[] memory temp; MultiVaultSFData[] memory sfData = new MultiVaultSFData[](1); sfData[0] = req_.superformsData; (liqAmount, srcAmount, dstAmount) = _calculateAmounts(CalculateAmountsReq(0, dstChainIds, req_.ambIds, sfData, temp, factory, isDeposit_)); totalAmount = srcAmount + dstAmount + liqAmount; } /// @inheritdoc IPaymentHelper function estimateSingleXChainSingleVault( SingleXChainSingleVaultStateReq calldata req_, bool isDeposit_ ) external view override returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount) { ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY"))); uint64[] memory dstChainIds = new uint64[](1); dstChainIds[0] = req_.dstChainId; MultiVaultSFData[] memory temp; SingleVaultSFData[] memory sfData = new SingleVaultSFData[](1); sfData[0] = req_.superformData; (liqAmount, srcAmount, dstAmount) = _calculateAmounts(CalculateAmountsReq(0, dstChainIds, req_.ambIds, temp, sfData, factory, isDeposit_)); totalAmount = srcAmount + dstAmount + liqAmount; } /// @inheritdoc IPaymentHelper function estimateSingleDirectSingleVault( SingleDirectSingleVaultStateReq calldata req_, bool isDeposit_ ) external view override returns (uint256 liqAmount, uint256 dstOrSameChainAmt, uint256 totalAmount) { ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY"))); uint64[] memory dstChainIds = new uint64[](1); dstChainIds[0] = CHAIN_ID; SingleVaultSFData[] memory sfData = new SingleVaultSFData[](1); sfData[0] = req_.superformData; MultiVaultSFData[] memory temp; uint8[] memory ambIds; (liqAmount,, dstOrSameChainAmt) = _calculateAmounts(CalculateAmountsReq(0, dstChainIds, ambIds, temp, sfData, factory, isDeposit_)); totalAmount = liqAmount + dstOrSameChainAmt; } /// @inheritdoc IPaymentHelper function estimateSingleDirectMultiVault( SingleDirectMultiVaultStateReq calldata req_, bool isDeposit_ ) external view override returns (uint256 liqAmount, uint256 dstOrSameChainAmt, uint256 totalAmount) { ISuperformFactory factory = ISuperformFactory(_getAddress(keccak256("SUPERFORM_FACTORY"))); uint64[] memory dstChainIds = new uint64[](1); dstChainIds[0] = CHAIN_ID; SingleVaultSFData[] memory temp; MultiVaultSFData[] memory sfData = new MultiVaultSFData[](1); sfData[0] = req_.superformData; uint8[] memory ambIds; (liqAmount,, dstOrSameChainAmt) = _calculateAmounts(CalculateAmountsReq(0, dstChainIds, ambIds, sfData, temp, factory, isDeposit_)); totalAmount = liqAmount + dstOrSameChainAmt; } /// @inheritdoc IPaymentHelper function estimateAMBFees( uint8[] memory ambIds_, uint64 dstChainId_, bytes memory message_, bytes[] memory extraData_ ) public view override returns (uint256 totalFees, uint256[] memory) { uint256 len = ambIds_.length; uint256[] memory fees = new uint256[](len); /// @dev just checks the estimate for sending message from src -> dst if (CHAIN_ID != dstChainId_) { for (uint256 i; i < len; ++i) { fees[i] = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).estimateFees( dstChainId_, message_, extraData_[i] ); totalFees += fees[i]; } } return (totalFees, fees); } /// @inheritdoc IPaymentHelper function estimateAckCost(uint256 payloadId_) external view override returns (uint256 totalFees) { EstimateAckCostVars memory v; IBaseStateRegistry coreStateRegistry = IBaseStateRegistry(_getAddress(keccak256("CORE_STATE_REGISTRY"))); v.currPayloadId = coreStateRegistry.payloadsCount(); if (payloadId_ > v.currPayloadId) revert Error.INVALID_PAYLOAD_ID(); v.payloadHeader = coreStateRegistry.payloadHeader(payloadId_); v.payloadBody = coreStateRegistry.payloadBody(payloadId_); (, v.callbackType, v.isMulti,,, v.srcChainId) = DataLib.decodeTxInfo(v.payloadHeader); /// if callback type is return then return 0 if (v.callbackType != 0) return 0; if (v.isMulti == 1) { InitMultiVaultData memory data = abi.decode(v.payloadBody, (InitMultiVaultData)); v.payloadBody = abi.encode(ReturnMultiData(v.currPayloadId, data.superformIds, data.amounts)); } else { InitSingleVaultData memory data = abi.decode(v.payloadBody, (InitSingleVaultData)); v.payloadBody = abi.encode(ReturnSingleData(v.currPayloadId, data.superformId, data.amount)); } v.ackAmbIds = coreStateRegistry.getMessageAMB(payloadId_); v.message = abi.encode(AMBMessage(coreStateRegistry.payloadHeader(payloadId_), v.payloadBody)); return _estimateAMBFees(v.ackAmbIds, v.srcChainId, v.message); } /// @inheritdoc IPaymentHelper function estimateAckCostDefault( bool multi, uint8[] memory ackAmbIds, uint64 srcChainId ) public view override returns (uint256 totalFees) { bytes memory payloadBody; if (multi) { uint256 vaultLimitPerDst = superRegistry.getVaultLimitPerDestination(srcChainId); uint256[] memory maxUints = new uint256[](vaultLimitPerDst); for (uint256 i; i < vaultLimitPerDst; ++i) { maxUints[i] = type(uint256).max; } payloadBody = abi.encode(ReturnMultiData(type(uint256).max, maxUints, maxUints)); } else { payloadBody = abi.encode(ReturnSingleData(type(uint256).max, type(uint256).max, type(uint256).max)); } return _estimateAMBFees(ackAmbIds, srcChainId, abi.encode(AMBMessage(type(uint256).max, payloadBody))); } /// @inheritdoc IPaymentHelper function estimateAckCostDefaultNativeSource( bool multi, uint8[] memory ackAmbIds, uint64 srcChainId ) external view override returns (uint256) { return _convertToSrcNativeAmount(srcChainId, estimateAckCostDefault(multi, ackAmbIds, srcChainId)); } ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @inheritdoc IPaymentHelper function addRemoteChain(uint64 chainId_, PaymentHelperConfig calldata config_) public override onlyProtocolAdmin { _addRemoteChain(chainId_, config_); } /// @inheritdoc IPaymentHelper function addRemoteChains( uint64[] calldata chainIds_, PaymentHelperConfig[] calldata configs_ ) external override onlyProtocolAdmin { uint256 len = chainIds_.length; if (len == 0) revert Error.ZERO_INPUT_VALUE(); if (len != configs_.length) revert Error.ARRAY_LENGTH_MISMATCH(); for (uint256 i; i < len; ++i) { _addRemoteChain(chainIds_[i], configs_[i]); } } /// @inheritdoc IPaymentHelper function updateRemoteChain( uint64 chainId_, uint256 configType_, bytes memory config_ ) external override onlyPaymentAdmin { _updateRemoteChain(chainId_, configType_, config_); } /// @inheritdoc IPaymentHelper function batchUpdateRemoteChain( uint64 chainId_, uint256[] calldata configTypes_, bytes[] calldata configs_ ) external override onlyPaymentAdmin { _batchUpdateRemoteChain(chainId_, configTypes_, configs_); } /// @inheritdoc IPaymentHelper function batchUpdateRemoteChains( uint64[] calldata chainIds_, uint256[][] calldata configTypes_, bytes[][] calldata configs_ ) external override onlyPaymentAdmin { uint256 len = chainIds_.length; if (len == 0) revert Error.ZERO_INPUT_VALUE(); if (!(len == configTypes_.length && len == configs_.length)) revert Error.ARRAY_LENGTH_MISMATCH(); for (uint256 i; i < len; ++i) { _batchUpdateRemoteChain(chainIds_[i], configTypes_[i], configs_[i]); } } /// @inheritdoc IPaymentHelper function updateRegisterAERC20Params(bytes memory extraDataForTransmuter_) external onlyPaymentAdmin { extraDataForTransmuter = extraDataForTransmuter_; } ////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS // ////////////////////////////////////////////////////////////// function _getOracleDecimals(AggregatorV3Interface oracle_) internal view returns (uint8) { return oracle_.decimals(); } /// @dev PROTOCOL_ADMIN can perform the configuration of a remote chain for the first time function _addRemoteChain(uint64 chainId_, PaymentHelperConfig calldata config_) internal { if (config_.nativeFeedOracle != address(0)) { AggregatorV3Interface nativeFeedOracleContract = AggregatorV3Interface(config_.nativeFeedOracle); if (_getOracleDecimals(nativeFeedOracleContract) != SUPPORTED_FEED_PRECISION) { revert Error.CHAINLINK_UNSUPPORTED_DECIMAL(); } nativeFeedOracle[chainId_] = nativeFeedOracleContract; } if (config_.gasPriceOracle != address(0)) { AggregatorV3Interface gasPriceOracleContract = AggregatorV3Interface(config_.gasPriceOracle); if (_getOracleDecimals(gasPriceOracleContract) != SUPPORTED_FEED_PRECISION) { revert Error.CHAINLINK_UNSUPPORTED_DECIMAL(); } gasPriceOracle[chainId_] = gasPriceOracleContract; } swapGasUsed[chainId_] = config_.swapGasUsed; updateDepositGasUsed[chainId_] = config_.updateDepositGasUsed; depositGasUsed[chainId_] = config_.depositGasUsed; withdrawGasUsed[chainId_] = config_.withdrawGasUsed; nativePrice[chainId_] = config_.defaultNativePrice; gasPrice[chainId_] = config_.defaultGasPrice; gasPerByte[chainId_] = config_.dstGasPerByte; ackGasCost[chainId_] = config_.ackGasCost; timelockCost[chainId_] = config_.timelockCost; emergencyCost[chainId_] = config_.emergencyCost; updateWithdrawGasUsed[chainId_] = config_.updateWithdrawGasUsed; emit ChainConfigAdded(chainId_, config_); } /// @dev PAYMENT_ADMIN can update the configuration of a remote chain on a need basis function _updateRemoteChain(uint64 chainId_, uint256 configType_, bytes memory config_) internal { /// @dev Type 1: DST TOKEN PRICE FEED ORACLE if (configType_ == 1) { AggregatorV3Interface nativeFeedOracleContract = AggregatorV3Interface(abi.decode(config_, (address))); /// @dev allows setting price feed to address(0), equivalent for resetting native price if ( address(nativeFeedOracleContract) != address(0) && _getOracleDecimals(nativeFeedOracleContract) != SUPPORTED_FEED_PRECISION ) { revert Error.CHAINLINK_UNSUPPORTED_DECIMAL(); } nativeFeedOracle[chainId_] = nativeFeedOracleContract; } /// @dev Type 2: DST GAS PRICE ORACLE if (configType_ == 2) { AggregatorV3Interface gasPriceOracleContract = AggregatorV3Interface(abi.decode(config_, (address))); /// @dev allows setting gas price to address(0), equivalent for resetting gas price if ( address(gasPriceOracleContract) != address(0) && _getOracleDecimals(gasPriceOracleContract) != SUPPORTED_FEED_PRECISION ) { revert Error.CHAINLINK_UNSUPPORTED_DECIMAL(); } gasPriceOracle[chainId_] = gasPriceOracleContract; } /// @dev Type 3: SWAP GAS USED if (configType_ == 3) { swapGasUsed[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 4: PAYLOAD UPDATE DEPOSIT GAS COST PER TX if (configType_ == 4) { updateDepositGasUsed[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 5: DEPOSIT GAS COST PER TX if (configType_ == 5) { depositGasUsed[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 6: WITHDRAW GAS COST PER TX if (configType_ == 6) { withdrawGasUsed[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 7: DEFAULT NATIVE PRICE if (configType_ == 7) { nativePrice[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 8: DEFAULT GAS PRICE if (configType_ == 8) { gasPrice[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 9: GAS PRICE PER Byte of Message if (configType_ == 9) { gasPerByte[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 10: ACK GAS COST if (configType_ == 10) { ackGasCost[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 11: TIMELOCK PROCESSING COST if (configType_ == 11) { timelockCost[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 12: EMERGENCY PROCESSING COST if (configType_ == 12) { emergencyCost[chainId_] = abi.decode(config_, (uint256)); } /// @dev Type 13: PAYLOAD UPDATE WITHDRAW GAS COST PER TX if (configType_ == 13) { updateWithdrawGasUsed[chainId_] = abi.decode(config_, (uint256)); } emit ChainConfigUpdated(chainId_, configType_, config_); } /// @dev batch updates the configuration of a remote chain. Performed by PAYMENT_ADMIN function _batchUpdateRemoteChain( uint64 chainId_, uint256[] calldata configTypes_, bytes[] calldata configs_ ) internal { uint256 len = configTypes_.length; if (len == 0) revert Error.ZERO_INPUT_VALUE(); if (len != configs_.length) revert Error.ARRAY_LENGTH_MISMATCH(); for (uint256 i; i < len; ++i) { _updateRemoteChain(chainId_, configTypes_[i], configs_[i]); } } /// @dev helps generate extra data per amb function _generateExtraData( uint64 dstChainId_, uint8[] memory ambIds_, bytes memory message_ ) internal view returns (bytes[] memory extraDataPerAMB) { AMBMessage memory ambIdEncodedMessage = abi.decode(message_, (AMBMessage)); ambIdEncodedMessage.params = abi.encode(ambIds_, ambIdEncodedMessage.params); uint256 len = ambIds_.length; uint256 gasReqPerByte = gasPerByte[dstChainId_]; uint256 totalDstGasReqInWei = abi.encode(ambIdEncodedMessage).length * gasReqPerByte; /// @dev proof length is always of fixed length uint256 totalDstGasReqInWeiForProof = PROOF_LENGTH * gasReqPerByte; extraDataPerAMB = new bytes[](len); for (uint256 i; i < len; ++i) { uint256 gasReq = i != 0 ? totalDstGasReqInWeiForProof : totalDstGasReqInWei; extraDataPerAMB[i] = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).generateExtraData(gasReq); } } /// @dev helps estimate the cross-chain message costs function _estimateAMBFees( uint8[] memory ambIds_, uint64 dstChainId_, bytes memory message_ ) internal view returns (uint256 totalFees) { uint256 len = ambIds_.length; bytes[] memory extraDataPerAMB = _generateExtraData(dstChainId_, ambIds_, message_); AMBMessage memory ambIdEncodedMessage = abi.decode(message_, (AMBMessage)); ambIdEncodedMessage.params = abi.encode(ambIds_, ambIdEncodedMessage.params); bytes memory proof_ = abi.encode(AMBMessage(MAX_UINT256, abi.encode(keccak256(message_)))); /// @dev just checks the estimate for sending message from src -> dst /// @dev only ambIds_[0] = primary amb (rest of the ambs send only the proof) if (CHAIN_ID != dstChainId_) { for (uint256 i; i < len; ++i) { uint256 tempFee = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).estimateFees( dstChainId_, i != 0 ? proof_ : abi.encode(ambIdEncodedMessage), extraDataPerAMB[i] ); totalFees += tempFee; } } } /// @dev helps estimate the cross-chain message costs function _estimateAMBFeesReturnExtraData( uint64 dstChainId_, uint8[] calldata ambIds_, bytes memory message_ ) internal view returns (uint256[] memory feeSplitUp, bytes[] memory extraDataPerAMB, uint256 totalFees) { AMBMessage memory ambIdEncodedMessage = abi.decode(message_, (AMBMessage)); ambIdEncodedMessage.params = abi.encode(ambIds_, ambIdEncodedMessage.params); uint256 len = ambIds_.length; extraDataPerAMB = _generateExtraData(dstChainId_, ambIds_, message_); feeSplitUp = new uint256[](len); bytes memory proof_ = abi.encode(AMBMessage(MAX_UINT256, abi.encode(keccak256(message_)))); /// @dev just checks the estimate for sending message from src -> dst if (CHAIN_ID != dstChainId_) { for (uint256 i; i < len; ++i) { uint256 tempFee = IAmbImplementation(superRegistry.getAmbAddress(ambIds_[i])).estimateFees( dstChainId_, i != 0 ? proof_ : abi.encode(ambIdEncodedMessage), extraDataPerAMB[i] ); totalFees += tempFee; feeSplitUp[i] = tempFee; } } } /// @dev helps estimate the liq amount involved in the tx function _estimateLiqAmount(LiqRequest[] memory req_) internal pure returns (uint256 liqAmount) { uint256 len = req_.length; for (uint256 i; i < len; ++i) { liqAmount += req_[i].nativeAmount; } } /// @dev helps estimate the dst chain swap gas limit (if multi-tx is involved) function _estimateSwapFees( uint64 dstChainId_, bool[] memory hasDstSwaps_ ) internal view returns (uint256 gasUsed) { uint256 totalSwaps; if (CHAIN_ID == dstChainId_) { return 0; } uint256 len = hasDstSwaps_.length; for (uint256 i; i < len; ++i) { /// @dev checks if hasDstSwap is true if (hasDstSwaps_[i]) { ++totalSwaps; } } if (totalSwaps == 0) { return 0; } return totalSwaps * swapGasUsed[dstChainId_]; } /// @dev helps estimate the dst chain update payload gas limit function _estimateUpdateDepositCost( uint64 dstChainId_, uint256 vaultsCount_ ) internal view returns (uint256 gasUsed) { return vaultsCount_ * updateDepositGasUsed[dstChainId_]; } /// @dev helps estimate the dst chain update payload gas limit function _estimateUpdateWithdrawCost( uint64 dstChainId_, LiqRequest[] memory liqRequests_ ) internal view returns (uint256 gasUsed) { uint256 len = liqRequests_.length; for (uint256 i; i < len; i++) { /// @dev liqRequests[i].token on withdraws is the desired token /// @dev if token is address(0) -> user wants settlement without any liq data /// @dev this means that if no txData is present and token is different than address(0) an update is /// required in destination if (liqRequests_[i].txData.length == 0 && liqRequests_[i].token != address(0)) { gasUsed += updateWithdrawGasUsed[dstChainId_]; } } } /// @dev helps estimate the dst chain processing cost including the dst->src message cost /// @dev assumes that withdrawals optimisically succeed function _estimateDstExecutionCost( bool isDeposit_, uint64 dstChainId_, uint256 vaultsCount_ ) internal view returns (uint256 gasUsed) { uint256 executionGasPerVault = isDeposit_ ? depositGasUsed[dstChainId_] : withdrawGasUsed[dstChainId_]; gasUsed = executionGasPerVault * vaultsCount_; } /// @dev helps estimate the src chain processing fee function _estimateAckProcessingCost(uint256 vaultsCount_) internal view returns (uint256 nativeFee) { uint256 gasCost = vaultsCount_ * ackGasCost[CHAIN_ID]; return gasCost * _getGasPrice(CHAIN_ID); } /// @dev generates the amb message for single vault data function _generateSingleVaultMessage(SingleVaultSFData memory sfData_) internal view returns (bytes memory message_) { bytes memory ambData = abi.encode( InitSingleVaultData( _getNextPayloadId(), sfData_.superformId, sfData_.amount, sfData_.outputAmount, sfData_.maxSlippage, sfData_.liqRequest, sfData_.hasDstSwap, sfData_.retain4626, sfData_.receiverAddress, sfData_.extraFormData ) ); message_ = abi.encode(AMBMessage(MAX_UINT256, ambData)); } /// @dev generates the amb message for multi vault data function _generateMultiVaultMessage(MultiVaultSFData memory sfData_) internal view returns (bytes memory message_) { bytes memory ambData = abi.encode( InitMultiVaultData( _getNextPayloadId(), sfData_.superformIds, sfData_.amounts, sfData_.outputAmounts, sfData_.maxSlippages, sfData_.liqRequests, sfData_.hasDstSwaps, sfData_.retain4626s, sfData_.receiverAddress, sfData_.extraFormData ) ); message_ = abi.encode(AMBMessage(MAX_UINT256, ambData)); } /// @dev helps convert the dst gas fee into src chain native fee /// @dev https://docs.soliditylang.org/en/v0.8.4/units-and-global-variables.html#ether-units /// @dev all native tokens should be 18 decimals across all EVMs function _convertToNativeFee( uint64 dstChainId_, uint256 dstGas_, bool xChain_ ) internal view returns (uint256 nativeFee) { /// @dev gas fee * gas price (to get the gas amounts in dst chain's native token) /// @dev gas price is 9 decimal (in gwei) /// @dev assumption: all evm native tokens are 18 decimals uint256 dstNativeFee = dstGas_ * _getGasPrice(dstChainId_); if (dstNativeFee == 0) { return 0; } if (!xChain_) { return dstNativeFee; } /// @dev converts the gas to pay in terms of native token to usd value /// @dev native token price is 8 decimal uint256 dstUsdValue = dstNativeFee * _getNativeTokenPrice(dstChainId_); // native token price - 8 decimal if (dstUsdValue == 0) { return 0; } /// @dev converts the usd value to source chain's native token /// @dev native token price is 8 decimal which cancels the 8 decimal multiplied in previous step uint256 nativeTokenPrice = _getNativeTokenPrice(CHAIN_ID); // native token price - 8 decimal if (nativeTokenPrice == 0) revert Error.INVALID_NATIVE_TOKEN_PRICE(); nativeFee = (dstUsdValue) / nativeTokenPrice; } /// @dev helps convert a native token of one chain to another /// @dev https://docs.soliditylang.org/en/v0.8.4/units-and-global-variables.html#ether-units /// @dev all native tokens should be 18 decimals across all EVMs function _convertToSrcNativeAmount( uint64 srcChainId_, uint256 dstAmount_ ) internal view returns (uint256 nativeFee) { if (dstAmount_ == 0) { return 0; } /// @dev converts the native token value to usd value /// @dev dstAmount_ is 18 decimal /// @dev native token price is 8 decimal uint256 dstUsdValue = dstAmount_ * _getNativeTokenPrice(CHAIN_ID); if (dstUsdValue == 0) { return 0; } /// @dev converts the usd value to source chain's native token /// @dev native token price is 8 decimal which cancels the 8 decimal multiplied in previous step uint256 nativeTokenPrice = _getNativeTokenPrice(srcChainId_); if (nativeTokenPrice == 0) revert Error.INVALID_NATIVE_TOKEN_PRICE(); nativeFee = dstUsdValue / nativeTokenPrice; } /// @dev helps generate the new payload id /// @dev next payload id = current payload id + 1 function _getNextPayloadId() internal view returns (uint256 nextPayloadId) { nextPayloadId = ReadOnlyBaseRegistry(_getAddress(keccak256("CORE_STATE_REGISTRY"))).payloadsCount(); ++nextPayloadId; } /// @dev helps return the current gas price of different networks /// @return native token price function _getGasPrice(uint64 chainId_) internal view returns (uint256) { address oracleAddr = address(gasPriceOracle[chainId_]); if (oracleAddr != address(0)) { try AggregatorV3Interface(oracleAddr).latestRoundData() returns ( uint80, int256 value, uint256, uint256 updatedAt, uint80 ) { if (value <= 0) revert Error.CHAINLINK_MALFUNCTION(); if (updatedAt == 0) revert Error.CHAINLINK_INCOMPLETE_ROUND(); return uint256(value); } catch { /// @dev do nothing and return the default price at the end of the function } } return gasPrice[chainId_]; } /// @dev helps return the dst chain token price of different networks /// @return native token price function _getNativeTokenPrice(uint64 chainId_) internal view returns (uint256) { address oracleAddr = address(nativeFeedOracle[chainId_]); if (oracleAddr != address(0)) { try AggregatorV3Interface(oracleAddr).latestRoundData() returns ( uint80, int256 dstTokenPrice, uint256, uint256 updatedAt, uint80 ) { if (dstTokenPrice <= 0) revert Error.CHAINLINK_MALFUNCTION(); if (updatedAt == 0) revert Error.CHAINLINK_INCOMPLETE_ROUND(); return uint256(dstTokenPrice); } catch { /// @dev do nothing and return the default price at the end of the function } } return nativePrice[chainId_]; } /// @dev returns the address from super registry function _getAddress(bytes32 id_) internal view returns (address) { return superRegistry.getAddress(id_); } /// @dev calculates different cost amounts involved in the tx function _calculateAmounts(CalculateAmountsReq memory req_) internal view returns (uint256 liqAmount, uint256 srcAmount, uint256 dstOrSameChainAmt) { LocalEstimateVars memory v; bool xChain = req_.dstChainIds[req_.i] != CHAIN_ID; /// @dev in xChain this is gas on the destination chain and in !xChain this is gas on the same chain v.totalGas = 0; bool multiVaults = req_.superformsData.length > 0; bytes memory message = multiVaults ? _generateMultiVaultMessage(req_.superformsData[req_.i]) : _generateSingleVaultMessage(req_.superformData[req_.i]); /// @dev step 1: estimate amb costs v.ambFees = xChain ? _estimateAMBFees(req_.ambIds, req_.dstChainIds[req_.i], message) : 0; v.superformIdsLen = multiVaults ? req_.superformsData[req_.i].superformIds.length : 1; srcAmount += v.ambFees; LiqRequest[] memory liqRequests = multiVaults ? req_.superformsData[req_.i].liqRequests : req_.superformData[req_.i].liqRequest.castLiqRequestToArray(); if (req_.isDeposit) { /// @dev step 2: estimate liq amount liqAmount += _estimateLiqAmount(liqRequests); if (xChain) { /// @dev step 3: estimate update cost (only for deposit) v.totalGas += _estimateUpdateDepositCost(req_.dstChainIds[req_.i], v.superformIdsLen); uint256 ackLen; if (multiVaults) { for (uint256 j; j < v.superformIdsLen; ++j) { if (!req_.superformsData[req_.i].retain4626s[j]) ++ackLen; } } else { if (!req_.superformData[req_.i].retain4626) ++ackLen; } /// @dev step 4: estimation processing cost of acknowledgement on source srcAmount += _estimateAckProcessingCost(ackLen); bool[] memory hasDstSwaps = multiVaults ? req_.superformsData[req_.i].hasDstSwaps : req_.superformData[req_.i].hasDstSwap.castBoolToArray(); /// @dev step 5: estimate dst swap cost if it exists v.totalGas += _estimateSwapFees(req_.dstChainIds[req_.i], hasDstSwaps); } } else { if (multiVaults) { /// @dev step 6: estimate if timelock form processing costs are involved for (uint256 j; j < v.superformIdsLen; ++j) { v.totalGas += _calculateTotalDstGasTimelockEmergency( req_.superformsData[req_.i].superformIds[j], req_.dstChainIds[req_.i], req_.factory ); } } else { v.totalGas += _calculateTotalDstGasTimelockEmergency( req_.superformData[req_.i].superformId, req_.dstChainIds[req_.i], req_.factory ); } if (xChain) { /// @dev step 7: estimate update withdraw cost if no txData is present v.totalGas += _estimateUpdateWithdrawCost(req_.dstChainIds[req_.i], liqRequests); } } /// @dev step 7: estimate execution costs in destination including sending acknowledgement to source /// @dev ensure that acknowledgement costs from dst to src are not double counted v.totalGas += xChain ? _estimateDstExecutionCost(req_.isDeposit, req_.dstChainIds[req_.i], v.superformIdsLen) : 0; /// @dev step 8: convert all dst/same chain gas estimates to src chain estimate (withdraw / deposit) dstOrSameChainAmt += _convertToNativeFee(req_.dstChainIds[req_.i], v.totalGas, xChain); } /// @dev calculates the srcAmount cost for single direct withdrawal function _calculateTotalDstGasTimelockEmergency( uint256 superformId_, uint64 dstChainId_, ISuperformFactory factory_ ) internal view returns (uint256 totalDstGas) { (, uint32 formId,) = superformId_.getSuperform(); bool paused = factory_.isFormImplementationPaused(formId); if (!paused && formId == TIMELOCK_FORM_ID) { totalDstGas += timelockCost[dstChainId_]; } else if (paused) { totalDstGas += emergencyCost[dstChainId_]; } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { MultiDstMultiVaultStateReq, MultiDstSingleVaultStateReq, SingleXChainMultiVaultStateReq, SingleXChainSingleVaultStateReq, SingleDirectSingleVaultStateReq, SingleDirectMultiVaultStateReq } from "src/types/DataTypes.sol"; /// @title IPaymentHelper /// @dev Interface for PaymentHelper /// @author ZeroPoint Labs interface IPaymentHelperV2 { ////////////////////////////////////////////////////////////// // STRUCTS // ////////////////////////////////////////////////////////////// /// @param nativeFeedOracle is the native price feed oracle /// @param gasPriceOracle is the gas price oracle /// @param swapGasUsed is the swap gas params /// @param updateDepositGasUsed is the update gas params /// @param depositGasUsed is the deposit per vault gas on the chain /// @param withdrawGasUsed is the withdraw per vault gas on the chain /// @param defaultNativePrice is the native price on the specified chain /// @param defaultGasPrice is the gas price on the specified chain /// @param dstGasPerByte is the gas per size of data on the specified chain /// @param ackGasCost is the gas cost for sending and processing from dst->src /// @param timelockCost is the extra cost for processing timelocked payloads /// @param emergencyCost is the extra cost for processing emergency payloads /// @param updateWithdrawGasUsed is the update gas params for withdraws struct PaymentHelperConfig { address nativeFeedOracle; address gasPriceOracle; uint256 swapGasUsed; uint256 updateDepositGasUsed; uint256 depositGasUsed; uint256 withdrawGasUsed; uint256 defaultNativePrice; uint256 defaultGasPrice; uint256 dstGasPerByte; uint256 ackGasCost; uint256 timelockCost; uint256 emergencyCost; uint256 updateWithdrawGasUsed; } ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// event ChainConfigUpdated(uint64 indexed chainId_, uint256 indexed configType_, bytes config_); event ChainConfigAdded(uint64 chainId_, PaymentHelperConfig config_); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev returns the amb overrides & gas to be used /// @param dstChainId_ is the unique dst chain identifier /// @param ambIds_ is the identifiers of arbitrary message bridges to be used /// @param message_ is the encoded cross-chain payload function calculateAMBData( uint64 dstChainId_, uint8[] calldata ambIds_, bytes memory message_ ) external view returns (uint256 totalFees, bytes memory extraData); /// @dev returns the amb overrides & gas to be used /// @return extraData the amb specific override information function getRegisterTransmuterAMBData() external view returns (bytes memory extraData); /// @dev estimates the gas fees for multiple destination and multi vault operation /// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter /// @param isDeposit_ indicated if the datatype will be used for a deposit /// @return liqAmount is the amount of liquidity to be provided in native tokens /// @return srcAmount is the gas expense on source chain in native tokens /// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens /// @return totalAmount is the native_tokens to be sent along the transaction function estimateMultiDstMultiVault( MultiDstMultiVaultStateReq calldata req_, bool isDeposit_ ) external view returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount); /// @dev estimates the gas fees for multiple destination and single vault operation /// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter /// @param isDeposit_ indicated if the datatype will be used for a deposit /// @return liqAmount is the amount of liquidity to be provided in native tokens /// @return srcAmount is the gas expense on source chain in native tokens /// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens /// @return totalAmount is the native_tokens to be sent along the transaction function estimateMultiDstSingleVault( MultiDstSingleVaultStateReq calldata req_, bool isDeposit_ ) external view returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount); /// @dev estimates the gas fees for single destination and multi vault operation /// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter /// @param isDeposit_ indicated if the datatype will be used for a deposit /// @return liqAmount is the amount of liquidity to be provided in native tokens /// @return srcAmount is the gas expense on source chain in native tokens /// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens /// @return totalAmount is the native_tokens to be sent along the transaction function estimateSingleXChainMultiVault( SingleXChainMultiVaultStateReq calldata req_, bool isDeposit_ ) external view returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount); /// @dev estimates the gas fees for single destination and single vault operation /// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter /// @param isDeposit_ indicated if the datatype will be used for a deposit /// @return liqAmount is the amount of liquidity to be provided in native tokens /// @return srcAmount is the gas expense on source chain in native tokens /// @return dstAmount is the gas expense on dst chain in terms of src chain's native tokens /// @return totalAmount is the native_tokens to be sent along the transaction function estimateSingleXChainSingleVault( SingleXChainSingleVaultStateReq calldata req_, bool isDeposit_ ) external view returns (uint256 liqAmount, uint256 srcAmount, uint256 dstAmount, uint256 totalAmount); /// @dev estimates the gas fees for same chain operation /// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter /// @param isDeposit_ indicated if the datatype will be used for a deposit /// @return liqAmount is the amount of liquidity to be provided in native tokens /// @return srcAmount is the gas expense on source chain in native tokens /// @return totalAmount is the native_tokens to be sent along the transaction function estimateSingleDirectSingleVault( SingleDirectSingleVaultStateReq calldata req_, bool isDeposit_ ) external view returns (uint256 liqAmount, uint256 srcAmount, uint256 totalAmount); /// @dev estimates the gas fees for multiple same chain operation /// @param req_ is the request object containing all necessary data for the actual operation on SuperRouter /// @param isDeposit_ indicated if the datatype will be used for a deposit /// @return liqAmount is the amount of liquidity to be provided in native tokens /// @return srcAmount is the gas expense on source chain in native tokens /// @return totalAmount is the native_tokens to be sent along the transaction function estimateSingleDirectMultiVault( SingleDirectMultiVaultStateReq calldata req_, bool isDeposit_ ) external view returns (uint256 liqAmount, uint256 srcAmount, uint256 totalAmount); /// @dev returns the gas fees estimation in native tokens if we send message through a combination of AMBs /// @param ambIds_ is the identifier of different AMBs /// @param dstChainId_ is the identifier of the destination chain /// @param message_ is the cross-chain message /// @param extraData_ is any amb-specific information /// @return ambFees is the native_tokens to be sent along the transaction for all the ambIds_ included function estimateAMBFees( uint8[] memory ambIds_, uint64 dstChainId_, bytes memory message_, bytes[] memory extraData_ ) external view returns (uint256 ambFees, uint256[] memory); /// @dev helps estimate the acknowledgement costs for amb processing /// @param payloadId_ is the payload identifier /// @return totalFees is the total fees to be paid in native tokens function estimateAckCost(uint256 payloadId_) external view returns (uint256 totalFees); /// @dev helps estimate the acknowledgement costs for amb processing without relying on payloadId (using max values) /// @param multi is the flag indicating if the payload is multi or single /// @param ackAmbIds is the list of ambIds to be used for acknowledgement /// @param srcChainId is the source chain identifier /// @return totalFees is the total fees to be paid in native tokens function estimateAckCostDefault( bool multi, uint8[] memory ackAmbIds, uint64 srcChainId ) external view returns (uint256 totalFees); /// @dev helps estimate the acknowledgement costs for amb processing without relying on payloadId (using max values) /// with source native amounts /// @param multi is the flag indicating if the payload is multi or single /// @param ackAmbIds is the list of ambIds to be used for acknowledgement /// @param srcChainId is the source chain identifier /// @return totalFees is the total fees to be paid in native tokens function estimateAckCostDefaultNativeSource( bool multi, uint8[] memory ackAmbIds, uint64 srcChainId ) external view returns (uint256 totalFees); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev admin can configure a remote chain for the first time /// @param chainId_ is the identifier of new chain id /// @param config_ is the chain config function addRemoteChain(uint64 chainId_, PaymentHelperConfig calldata config_) external; /// @dev admin can configure various remote chain for the first time in a single call /// @param chainIds_ is the identifier of new chain id /// @param configs_ is the chain config function addRemoteChains(uint64[] calldata chainIds_, PaymentHelperConfig[] calldata configs_) external; /// @dev admin can specifically configure/update certain configuration of a remote chain /// @param chainId_ is the remote chain's identifier /// @param configType_ is the type of config from 1 -> 6 /// @param config_ is the encoded new configuration function updateRemoteChain(uint64 chainId_, uint256 configType_, bytes memory config_) external; /// @dev admin can specifically configure/update certain configurations on a single remote chain /// @param chainId_ are the remote chain's identifier /// @param configTypes_ are the type of config from 1 -> 6 for the given chain /// @param configs_ are the encoded new configurations for each config type for the given chain function batchUpdateRemoteChain( uint64 chainId_, uint256[] calldata configTypes_, bytes[] calldata configs_ ) external; /// @dev admin can specifically configure/update certain configurations on various remote chains at the same time /// @param chainIds_ are the remote chain's identifier /// @param configTypes_ are the type of config from 1 -> 6 for each chain /// @param configs_ are the encoded new configurations for each config type and chains function batchUpdateRemoteChains( uint64[] calldata chainIds_, uint256[][] calldata configTypes_, bytes[][] calldata configs_ ) external; /// @dev admin updates config for register transmuter amb params /// @param extraDataForTransmuter_ is the broadcast extra data function updateRegisterAERC20Params(bytes memory extraDataForTransmuter_) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { IAccessControl } from "openzeppelin-contracts/contracts/access/IAccessControl.sol"; /// @title ISuperRBAC /// @dev Interface for SuperRBAC /// @author Zeropoint Labs interface ISuperRBAC is IAccessControl { ////////////////////////////////////////////////////////////// // STRUCTS // ////////////////////////////////////////////////////////////// struct InitialRoleSetup { address admin; address emergencyAdmin; address paymentAdmin; address csrProcessor; address tlProcessor; address brProcessor; address csrUpdater; address srcVaaRelayer; address dstSwapper; address csrRescuer; address csrDisputer; } ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev is emitted when superRegistry is set event SuperRegistrySet(address indexed superRegistry); /// @dev is emitted when an admin is set for a role event RoleAdminSet(bytes32 role, bytes32 adminRole); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev returns the id of the protocol admin role function PROTOCOL_ADMIN_ROLE() external view returns (bytes32); /// @dev returns the id of the emergency admin role function EMERGENCY_ADMIN_ROLE() external view returns (bytes32); /// @dev returns the id of the payment admin role function PAYMENT_ADMIN_ROLE() external view returns (bytes32); /// @dev returns the id of the broadcaster role function BROADCASTER_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry processor role function CORE_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32); /// @dev returns the id of the timelock state registry processor role function TIMELOCK_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32); /// @dev returns the id of the broadcast state registry processor role function BROADCAST_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry updater role function CORE_STATE_REGISTRY_UPDATER_ROLE() external view returns (bytes32); /// @dev returns the id of the dst swapper role function DST_SWAPPER_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry rescuer role function CORE_STATE_REGISTRY_RESCUER_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry rescue disputer role function CORE_STATE_REGISTRY_DISPUTER_ROLE() external view returns (bytes32); /// @dev returns the id of wormhole vaa relayer role function WORMHOLE_VAA_RELAYER_ROLE() external view returns (bytes32); /// @dev returns whether the given address has the protocol admin role /// @param admin_ the address to check function hasProtocolAdminRole(address admin_) external view returns (bool); /// @dev returns whether the given address has the emergency admin role /// @param admin_ the address to check function hasEmergencyAdminRole(address admin_) external view returns (bool); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev updates the super registry address function setSuperRegistry(address superRegistry_) external; /// @dev configures a new role in superForm /// @param role_ the role to set /// @param adminRole_ the admin role to set as admin function setRoleAdmin(bytes32 role_, bytes32 adminRole_) external; /// @dev revokes the role_ from superRegistryAddressId_ on all chains /// @param role_ the role to revoke /// @param extraData_ amb config if broadcasting is required /// @param superRegistryAddressId_ the super registry address id function revokeRoleSuperBroadcast( bytes32 role_, bytes memory extraData_, bytes32 superRegistryAddressId_ ) external payable; /// @dev allows sync of global roles from different chains using broadcast registry /// @notice may not work for all roles function stateSyncBroadcast(bytes memory data_) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; /// @title ISuperRegistry /// @dev Interface for SuperRegistry /// @author Zeropoint Labs interface ISuperRegistry { ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev emitted when permit2 is set. event SetPermit2(address indexed permit2); /// @dev is emitted when an address is set. event AddressUpdated( bytes32 indexed protocolAddressId, uint64 indexed chainId, address indexed oldAddress, address newAddress ); /// @dev is emitted when a new token bridge is configured. event SetBridgeAddress(uint256 indexed bridgeId, address indexed bridgeAddress); /// @dev is emitted when a new bridge validator is configured. event SetBridgeValidator(uint256 indexed bridgeId, address indexed bridgeValidator); /// @dev is emitted when a new amb is configured. event SetAmbAddress(uint8 indexed ambId_, address indexed ambAddress_, bool indexed isBroadcastAMB_); /// @dev is emitted when a new state registry is configured. event SetStateRegistryAddress(uint8 indexed registryId_, address indexed registryAddress_); /// @dev is emitted when a new delay is configured. event SetDelay(uint256 indexed oldDelay_, uint256 indexed newDelay_); /// @dev is emitted when a new vault limit is configured event SetVaultLimitPerDestination(uint64 indexed chainId_, uint256 indexed vaultLimit_); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev gets the deposit rescue delay function delay() external view returns (uint256); /// @dev returns the permit2 address function PERMIT2() external view returns (address); /// @dev returns the id of the superform router module function SUPERFORM_ROUTER() external view returns (bytes32); /// @dev returns the id of the superform factory module function SUPERFORM_FACTORY() external view returns (bytes32); /// @dev returns the id of the superform paymaster contract function PAYMASTER() external view returns (bytes32); /// @dev returns the id of the superform payload helper contract function PAYMENT_HELPER() external view returns (bytes32); /// @dev returns the id of the core state registry module function CORE_STATE_REGISTRY() external view returns (bytes32); /// @dev returns the id of the timelock form state registry module function TIMELOCK_STATE_REGISTRY() external view returns (bytes32); /// @dev returns the id of the broadcast state registry module function BROADCAST_REGISTRY() external view returns (bytes32); /// @dev returns the id of the super positions module function SUPER_POSITIONS() external view returns (bytes32); /// @dev returns the id of the super rbac module function SUPER_RBAC() external view returns (bytes32); /// @dev returns the id of the payload helper module function PAYLOAD_HELPER() external view returns (bytes32); /// @dev returns the id of the dst swapper keeper function DST_SWAPPER() external view returns (bytes32); /// @dev returns the id of the emergency queue function EMERGENCY_QUEUE() external view returns (bytes32); /// @dev returns the id of the superform receiver function SUPERFORM_RECEIVER() external view returns (bytes32); /// @dev returns the id of the payment admin keeper function PAYMENT_ADMIN() external view returns (bytes32); /// @dev returns the id of the core state registry processor keeper function CORE_REGISTRY_PROCESSOR() external view returns (bytes32); /// @dev returns the id of the broadcast registry processor keeper function BROADCAST_REGISTRY_PROCESSOR() external view returns (bytes32); /// @dev returns the id of the timelock form state registry processor keeper function TIMELOCK_REGISTRY_PROCESSOR() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function CORE_REGISTRY_UPDATER() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function CORE_REGISTRY_RESCUER() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function CORE_REGISTRY_DISPUTER() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function DST_SWAPPER_PROCESSOR() external view returns (bytes32); /// @dev gets the address of a contract on current chain /// @param id_ is the id of the contract function getAddress(bytes32 id_) external view returns (address); /// @dev gets the address of a contract on a target chain /// @param id_ is the id of the contract /// @param chainId_ is the chain id of that chain function getAddressByChainId(bytes32 id_, uint64 chainId_) external view returns (address); /// @dev gets the address of a bridge /// @param bridgeId_ is the id of a bridge /// @return bridgeAddress_ is the address of the form function getBridgeAddress(uint8 bridgeId_) external view returns (address bridgeAddress_); /// @dev gets the address of a bridge validator /// @param bridgeId_ is the id of a bridge /// @return bridgeValidator_ is the address of the form function getBridgeValidator(uint8 bridgeId_) external view returns (address bridgeValidator_); /// @dev gets the address of a amb /// @param ambId_ is the id of a bridge /// @return ambAddress_ is the address of the form function getAmbAddress(uint8 ambId_) external view returns (address ambAddress_); /// @dev gets the id of the amb /// @param ambAddress_ is the address of an amb /// @return ambId_ is the identifier of an amb function getAmbId(address ambAddress_) external view returns (uint8 ambId_); /// @dev gets the address of the registry /// @param registryId_ is the id of the state registry /// @return registryAddress_ is the address of the state registry function getStateRegistry(uint8 registryId_) external view returns (address registryAddress_); /// @dev gets the id of the registry /// @notice reverts if the id is not found /// @param registryAddress_ is the address of the state registry /// @return registryId_ is the id of the state registry function getStateRegistryId(address registryAddress_) external view returns (uint8 registryId_); /// @dev gets the safe vault limit /// @param chainId_ is the id of the remote chain /// @return vaultLimitPerDestination_ is the safe number of vaults to deposit /// without hitting out of gas error function getVaultLimitPerDestination(uint64 chainId_) external view returns (uint256 vaultLimitPerDestination_); /// @dev helps validate if an address is a valid state registry /// @param registryAddress_ is the address of the state registry /// @return valid_ a flag indicating if its valid. function isValidStateRegistry(address registryAddress_) external view returns (bool valid_); /// @dev helps validate if an address is a valid amb implementation /// @param ambAddress_ is the address of the amb implementation /// @return valid_ a flag indicating if its valid. function isValidAmbImpl(address ambAddress_) external view returns (bool valid_); /// @dev helps validate if an address is a valid broadcast amb implementation /// @param ambAddress_ is the address of the broadcast amb implementation /// @return valid_ a flag indicating if its valid. function isValidBroadcastAmbImpl(address ambAddress_) external view returns (bool valid_); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev sets the deposit rescue delay /// @param delay_ the delay in seconds before the deposit rescue can be finalized function setDelay(uint256 delay_) external; /// @dev sets the permit2 address /// @param permit2_ the address of the permit2 contract function setPermit2(address permit2_) external; /// @dev sets the safe vault limit /// @param chainId_ is the remote chain identifier /// @param vaultLimit_ is the max limit of vaults per transaction function setVaultLimitPerDestination(uint64 chainId_, uint256 vaultLimit_) external; /// @dev sets new addresses on specific chains. /// @param ids_ are the identifiers of the address on that chain /// @param newAddresses_ are the new addresses on that chain /// @param chainIds_ are the chain ids of that chain function batchSetAddress( bytes32[] calldata ids_, address[] calldata newAddresses_, uint64[] calldata chainIds_ ) external; /// @dev sets a new address on a specific chain. /// @param id_ the identifier of the address on that chain /// @param newAddress_ the new address on that chain /// @param chainId_ the chain id of that chain function setAddress(bytes32 id_, address newAddress_, uint64 chainId_) external; /// @dev allows admin to set the bridge address for an bridge id. /// @notice this function operates in an APPEND-ONLY fashion. /// @param bridgeId_ represents the bridge unique identifier. /// @param bridgeAddress_ represents the bridge address. /// @param bridgeValidator_ represents the bridge validator address. function setBridgeAddresses( uint8[] memory bridgeId_, address[] memory bridgeAddress_, address[] memory bridgeValidator_ ) external; /// @dev allows admin to set the amb address for an amb id. /// @notice this function operates in an APPEND-ONLY fashion. /// @param ambId_ represents the bridge unique identifier. /// @param ambAddress_ represents the bridge address. /// @param isBroadcastAMB_ represents whether the amb implementation supports broadcasting function setAmbAddress( uint8[] memory ambId_, address[] memory ambAddress_, bool[] memory isBroadcastAMB_ ) external; /// @dev allows admin to set the state registry address for an state registry id. /// @notice this function operates in an APPEND-ONLY fashion. /// @param registryId_ represents the state registry's unique identifier. /// @param registryAddress_ represents the state registry's address. function setStateRegistryAddress(uint8[] memory registryId_, address[] memory registryAddress_) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; /// @title ISuperformFactory /// @dev Interface for SuperformFactory /// @author ZeroPoint Labs interface ISuperformFactory { ////////////////////////////////////////////////////////////// // CONSTANTS // ////////////////////////////////////////////////////////////// enum PauseStatus { NON_PAUSED, PAUSED } ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev emitted when a new formImplementation is entered into the factory /// @param formImplementation is the address of the new form implementation /// @param formImplementationId is the id of the formImplementation /// @param formStateRegistryId is any additional state registry id of the formImplementation event FormImplementationAdded( address indexed formImplementation, uint256 indexed formImplementationId, uint8 indexed formStateRegistryId ); /// @dev emitted when a new Superform is created /// @param formImplementationId is the id of the form implementation /// @param vault is the address of the vault /// @param superformId is the id of the superform /// @param superform is the address of the superform event SuperformCreated( uint256 indexed formImplementationId, address indexed vault, uint256 indexed superformId, address superform ); /// @dev emitted when a new SuperRegistry is set /// @param superRegistry is the address of the super registry event SuperRegistrySet(address indexed superRegistry); /// @dev emitted when a form implementation is paused /// @param formImplementationId is the id of the form implementation /// @param paused is the new paused status event FormImplementationPaused(uint256 indexed formImplementationId, PauseStatus indexed paused); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev returns the number of forms /// @return forms_ is the number of forms function getFormCount() external view returns (uint256 forms_); /// @dev returns the number of superforms /// @return superforms_ is the number of superforms function getSuperformCount() external view returns (uint256 superforms_); /// @dev returns the address of a form implementation /// @param formImplementationId_ is the id of the form implementation /// @return formImplementation_ is the address of the form implementation function getFormImplementation(uint32 formImplementationId_) external view returns (address formImplementation_); /// @dev returns the form state registry id of a form implementation /// @param formImplementationId_ is the id of the form implementation /// @return stateRegistryId_ is the additional state registry id of the form function getFormStateRegistryId(uint32 formImplementationId_) external view returns (uint8 stateRegistryId_); /// @dev returns the paused status of form implementation /// @param formImplementationId_ is the id of the form implementation /// @return paused_ is the current paused status of the form formImplementationId_ function isFormImplementationPaused(uint32 formImplementationId_) external view returns (bool paused_); /// @dev returns the address of a superform /// @param superformId_ is the id of the superform /// @return superform_ is the address of the superform /// @return formImplementationId_ is the id of the form implementation /// @return chainId_ is the chain id function getSuperform(uint256 superformId_) external pure returns (address superform_, uint32 formImplementationId_, uint64 chainId_); /// @dev returns if an address has been added to a Form /// @param superformId_ is the id of the superform /// @return isSuperform_ bool if it exists function isSuperform(uint256 superformId_) external view returns (bool isSuperform_); /// @dev Reverse query of getSuperform, returns all superforms for a given vault /// @param vault_ is the address of a vault /// @return superformIds_ is the id of the superform /// @return superforms_ is the address of the superform function getAllSuperformsFromVault(address vault_) external view returns (uint256[] memory superformIds_, address[] memory superforms_); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev allows an admin to add a Form implementation to the factory /// @param formImplementation_ is the address of a form implementation /// @param formImplementationId_ is the id of the form implementation (generated off-chain and equal in all chains) /// @param formStateRegistryId_ is the id of any additional state registry for that form /// @dev formStateRegistryId_ 1 is default for all form implementations, pass in formStateRegistryId_ only if an /// additional state registry is required function addFormImplementation( address formImplementation_, uint32 formImplementationId_, uint8 formStateRegistryId_ ) external; /// @dev To add new vaults to Form implementations, fusing them together into Superforms /// @param formImplementationId_ is the form implementation we want to attach the vault to /// @param vault_ is the address of the vault /// @return superformId_ is the id of the created superform /// @return superform_ is the address of the created superform function createSuperform( uint32 formImplementationId_, address vault_ ) external returns (uint256 superformId_, address superform_); /// @dev to synchronize superforms added to different chains using broadcast registry /// @param data_ is the cross-chain superform id function stateSyncBroadcast(bytes memory data_) external payable; /// @dev allows an admin to change the status of a form /// @param formImplementationId_ is the id of the form implementation /// @param status_ is the new status /// @param extraData_ is optional & passed when broadcasting of status is needed function changeFormImplementationPauseStatus( uint32 formImplementationId_, PauseStatus status_, bytes memory extraData_ ) external payable; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { PayloadState } from "src/types/DataTypes.sol"; /// @title IBaseStateRegistry /// @dev Interface for BaseStateRegistry /// @author ZeroPoint Labs interface IBaseStateRegistry { ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev is emitted when a cross-chain payload is received in the state registry event PayloadReceived(uint64 indexed srcChainId, uint64 indexed dstChainId, uint256 indexed payloadId); /// @dev is emitted when a cross-chain proof is received in the state registry /// NOTE: comes handy if quorum required is more than 0 event ProofReceived(bytes32 indexed proof); /// @dev is emitted when a payload id gets updated event PayloadUpdated(uint256 indexed payloadId); /// @dev is emitted when a payload id gets processed event PayloadProcessed(uint256 indexed payloadId); /// @dev is emitted when the super registry address is updated event SuperRegistryUpdated(address indexed superRegistry); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev allows users to read the total payloads received by the registry function payloadsCount() external view returns (uint256); /// @dev allows user to read the payload state /// uint256 payloadId_ is the unique payload identifier allocated on the destination chain function payloadTracking(uint256 payloadId_) external view returns (PayloadState payloadState_); /// @dev allows users to read the bytes payload_ stored per payloadId_ /// @param payloadId_ is the unique payload identifier allocated on the destination chain /// @return payloadBody_ the crosschain data received function payloadBody(uint256 payloadId_) external view returns (bytes memory payloadBody_); /// @dev allows users to read the uint256 payloadHeader stored per payloadId_ /// @param payloadId_ is the unique payload identifier allocated on the destination chain /// @return payloadHeader_ the crosschain header received function payloadHeader(uint256 payloadId_) external view returns (uint256 payloadHeader_); /// @dev allows users to read the ambs that delivered the payload id /// @param payloadId_ is the unique payload identifier allocated on the destination chain /// @return ambIds_ is the identifier of ambs that delivered the message and proof function getMessageAMB(uint256 payloadId_) external view returns (uint8[] memory ambIds_); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev allows core contracts to send payload to a destination chain. /// @param srcSender_ is the caller of the function (used for gas refunds). /// @param ambIds_ is the identifier of the arbitrary message bridge to be used /// @param dstChainId_ is the internal chainId used throughout the protocol /// @param message_ is the crosschain payload to be sent /// @param extraData_ defines all the message bridge related overrides /// NOTE: dstChainId_ is mapped to message bridge's destination id inside it's implementation contract /// NOTE: ambIds_ are superform assigned unique identifier for arbitrary message bridges function dispatchPayload( address srcSender_, uint8[] memory ambIds_, uint64 dstChainId_, bytes memory message_, bytes memory extraData_ ) external payable; /// @dev allows state registry to receive messages from message bridge implementations /// @param srcChainId_ is the superform chainId from which the payload is dispatched/sent /// @param message_ is the crosschain payload received /// NOTE: Only {IMPLEMENTATION_CONTRACT} role can call this function. function receivePayload(uint64 srcChainId_, bytes memory message_) external; /// @dev allows privileged actors to process cross-chain payloads /// @param payloadId_ is the identifier of the cross-chain payload /// NOTE: Only {CORE_STATE_REGISTRY_PROCESSOR_ROLE} role can call this function /// NOTE: this should handle reverting the state on source chain in-case of failure /// (or) can implement scenario based reverting like in coreStateRegistry function processPayload(uint256 payloadId_) external payable; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; /// @title IAmbImplementation /// @dev Interface for arbitrary message bridge (AMB) implementations /// @author ZeroPoint Labs interface IAmbImplementation { ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// event ChainAdded(uint64 indexed superChainId); event AuthorizedImplAdded(uint64 indexed superChainId, address indexed authImpl); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev returns the gas fees estimation in native tokens /// @notice not all AMBs will have on-chain estimation for which this function will return 0 /// @param dstChainId_ is the identifier of the destination chain /// @param message_ is the cross-chain message /// @param extraData_ is any amb-specific information /// @return fees is the native_tokens to be sent along the transaction function estimateFees( uint64 dstChainId_, bytes memory message_, bytes memory extraData_ ) external view returns (uint256 fees); /// @dev returns the extra data for the given gas request /// @param gasLimit is the amount of gas limit in wei to override /// @return extraData is the bytes encoded extra data /// NOTE: this process is unique to the message bridge function generateExtraData(uint256 gasLimit) external pure returns (bytes memory extraData); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev allows state registry to send message via implementation. /// @param srcSender_ is the caller (used for gas refunds) /// @param dstChainId_ is the identifier of the destination chain /// @param message_ is the cross-chain message to be sent /// @param extraData_ is message amb specific override information function dispatchPayload( address srcSender_, uint64 dstChainId_, bytes memory message_, bytes memory extraData_ ) external payable; /// @dev allows for the permissionless calling of the retry mechanism for encoded data /// @param data_ is the encoded retry data (different per AMB implementation) function retryPayload(bytes memory data_) external payable; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; library Error { ////////////////////////////////////////////////////////////// // CONFIGURATION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown in protocol setup /// @dev thrown if chain id exceeds max(uint64) error BLOCK_CHAIN_ID_OUT_OF_BOUNDS(); /// @dev thrown if not possible to revoke a role in broadcasting error CANNOT_REVOKE_NON_BROADCASTABLE_ROLES(); /// @dev thrown if not possible to revoke last admin error CANNOT_REVOKE_LAST_ADMIN(); /// @dev thrown if trying to set again pseudo immutables in super registry error DISABLED(); /// @dev thrown if rescue delay is not yet set for a chain error DELAY_NOT_SET(); /// @dev thrown if get native token price estimate in paymentHelper is 0 error INVALID_NATIVE_TOKEN_PRICE(); /// @dev thrown if wormhole refund chain id is not set error REFUND_CHAIN_ID_NOT_SET(); /// @dev thrown if wormhole relayer is not set error RELAYER_NOT_SET(); /// @dev thrown if a role to be revoked is not assigned error ROLE_NOT_ASSIGNED(); ////////////////////////////////////////////////////////////// // AUTHORIZATION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown if functions cannot be called /// COMMON AUTHORIZATION ERRORS /// --------------------------------------------------------- /// @dev thrown if caller is not address(this), internal call error INVALID_INTERNAL_CALL(); /// @dev thrown if msg.sender is not a valid amb implementation error NOT_AMB_IMPLEMENTATION(); /// @dev thrown if msg.sender is not an allowed broadcaster error NOT_ALLOWED_BROADCASTER(); /// @dev thrown if msg.sender is not broadcast amb implementation error NOT_BROADCAST_AMB_IMPLEMENTATION(); /// @dev thrown if msg.sender is not broadcast state registry error NOT_BROADCAST_REGISTRY(); /// @dev thrown if msg.sender is not core state registry error NOT_CORE_STATE_REGISTRY(); /// @dev thrown if msg.sender is not emergency admin error NOT_EMERGENCY_ADMIN(); /// @dev thrown if msg.sender is not emergency queue error NOT_EMERGENCY_QUEUE(); /// @dev thrown if msg.sender is not minter error NOT_MINTER(); /// @dev thrown if msg.sender is not minter state registry error NOT_MINTER_STATE_REGISTRY_ROLE(); /// @dev thrown if msg.sender is not paymaster error NOT_PAYMASTER(); /// @dev thrown if msg.sender is not payment admin error NOT_PAYMENT_ADMIN(); /// @dev thrown if msg.sender is not protocol admin error NOT_PROTOCOL_ADMIN(); /// @dev thrown if msg.sender is not state registry error NOT_STATE_REGISTRY(); /// @dev thrown if msg.sender is not super registry error NOT_SUPER_REGISTRY(); /// @dev thrown if msg.sender is not superform router error NOT_SUPERFORM_ROUTER(); /// @dev thrown if msg.sender is not a superform error NOT_SUPERFORM(); /// @dev thrown if msg.sender is not superform factory error NOT_SUPERFORM_FACTORY(); /// @dev thrown if msg.sender is not timelock form error NOT_TIMELOCK_SUPERFORM(); /// @dev thrown if msg.sender is not timelock state registry error NOT_TIMELOCK_STATE_REGISTRY(); /// @dev thrown if msg.sender is not user or disputer error NOT_VALID_DISPUTER(); /// @dev thrown if the msg.sender is not privileged caller error NOT_PRIVILEGED_CALLER(bytes32 role); /// STATE REGISTRY AUTHORIZATION ERRORS /// --------------------------------------------------------- /// @dev layerzero adapter specific error, thrown if caller not layerzero endpoint error CALLER_NOT_ENDPOINT(); /// @dev hyperlane adapter specific error, thrown if caller not hyperlane mailbox error CALLER_NOT_MAILBOX(); /// @dev wormhole relayer specific error, thrown if caller not wormhole relayer error CALLER_NOT_RELAYER(); /// @dev thrown if src chain sender is not valid error INVALID_SRC_SENDER(); ////////////////////////////////////////////////////////////// // INPUT VALIDATION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown if input variables are not valid /// COMMON INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if there is an array length mismatch error ARRAY_LENGTH_MISMATCH(); /// @dev thrown if payload id does not exist error INVALID_PAYLOAD_ID(); /// @dev error thrown when msg value should be zero in certain payable functions error MSG_VALUE_NOT_ZERO(); /// @dev thrown if amb ids length is 0 error ZERO_AMB_ID_LENGTH(); /// @dev thrown if address input is address 0 error ZERO_ADDRESS(); /// @dev thrown if amount input is 0 error ZERO_AMOUNT(); /// @dev thrown if final token is address 0 error ZERO_FINAL_TOKEN(); /// @dev thrown if value input is 0 error ZERO_INPUT_VALUE(); /// SUPERFORM ROUTER INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if the vaults data is invalid error INVALID_SUPERFORMS_DATA(); /// @dev thrown if receiver address is not set error RECEIVER_ADDRESS_NOT_SET(); /// SUPERFORM FACTORY INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if a form is not ERC165 compatible error ERC165_UNSUPPORTED(); /// @dev thrown if a form is not form interface compatible error FORM_INTERFACE_UNSUPPORTED(); /// @dev error thrown if form implementation address already exists error FORM_IMPLEMENTATION_ALREADY_EXISTS(); /// @dev error thrown if form implementation id already exists error FORM_IMPLEMENTATION_ID_ALREADY_EXISTS(); /// @dev thrown if a form does not exist error FORM_DOES_NOT_EXIST(); /// @dev thrown if form id is larger than max uint16 error INVALID_FORM_ID(); /// @dev thrown if superform not on factory error SUPERFORM_ID_NONEXISTENT(); /// @dev thrown if same vault and form implementation is used to create new superform error VAULT_FORM_IMPLEMENTATION_COMBINATION_EXISTS(); /// FORM INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if in case of no txData, if liqData.token != vault.asset() /// in case of txData, if token output of swap != vault.asset() error DIFFERENT_TOKENS(); /// @dev thrown if the amount in direct withdraw is not correct error DIRECT_WITHDRAW_INVALID_LIQ_REQUEST(); /// @dev thrown if the amount in xchain withdraw is not correct error XCHAIN_WITHDRAW_INVALID_LIQ_REQUEST(); /// LIQUIDITY BRIDGE INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if route id is blacklisted in socket error BLACKLISTED_ROUTE_ID(); /// @dev thrown if route id is not blacklisted in socket error NOT_BLACKLISTED_ROUTE_ID(); /// @dev error thrown when txData selector of lifi bridge is a blacklisted selector error BLACKLISTED_SELECTOR(); /// @dev error thrown when txData selector of lifi bridge is not a blacklisted selector error NOT_BLACKLISTED_SELECTOR(); /// @dev thrown if a certain action of the user is not allowed given the txData provided error INVALID_ACTION(); /// @dev thrown if in deposits, the liqDstChainId doesn't match the stateReq dstChainId error INVALID_DEPOSIT_LIQ_DST_CHAIN_ID(); /// @dev thrown if index is invalid error INVALID_INDEX(); /// @dev thrown if the chain id in the txdata is invalid error INVALID_TXDATA_CHAIN_ID(); /// @dev thrown if the validation of bridge txData fails due to a destination call present error INVALID_TXDATA_NO_DESTINATIONCALL_ALLOWED(); /// @dev thrown if the validation of bridge txData fails due to wrong receiver error INVALID_TXDATA_RECEIVER(); /// @dev thrown if the validation of bridge txData fails due to wrong token error INVALID_TXDATA_TOKEN(); /// @dev thrown if txData is not present (in case of xChain actions) error NO_TXDATA_PRESENT(); /// STATE REGISTRY INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if payload is being updated with final amounts length different than amounts length error DIFFERENT_PAYLOAD_UPDATE_AMOUNTS_LENGTH(); /// @dev thrown if payload is being updated with tx data length different than liq data length error DIFFERENT_PAYLOAD_UPDATE_TX_DATA_LENGTH(); /// @dev thrown if keeper update final token is different than the vault underlying error INVALID_UPDATE_FINAL_TOKEN(); /// @dev thrown if broadcast finality for wormhole is invalid error INVALID_BROADCAST_FINALITY(); /// @dev thrown if amb id is not valid leading to an address 0 of the implementation error INVALID_BRIDGE_ID(); /// @dev thrown if chain id involved in xchain message is invalid error INVALID_CHAIN_ID(); /// @dev thrown if payload update amount isn't equal to dst swapper amount error INVALID_DST_SWAP_AMOUNT(); /// @dev thrown if message amb and proof amb are the same error INVALID_PROOF_BRIDGE_ID(); /// @dev thrown if order of proof AMBs is incorrect, either duplicated or not incrementing error INVALID_PROOF_BRIDGE_IDS(); /// @dev thrown if rescue data lengths are invalid error INVALID_RESCUE_DATA(); /// @dev thrown if delay is invalid error INVALID_TIMELOCK_DELAY(); /// @dev thrown if amounts being sent in update payload mean a negative slippage error NEGATIVE_SLIPPAGE(); /// @dev thrown if slippage is outside of bounds error SLIPPAGE_OUT_OF_BOUNDS(); /// SUPERPOSITION INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if src senders mismatch in state sync error SRC_SENDER_MISMATCH(); /// @dev thrown if src tx types mismatch in state sync error SRC_TX_TYPE_MISMATCH(); ////////////////////////////////////////////////////////////// // EXECUTION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown due to function execution logic /// COMMON EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if the swap in a direct deposit resulted in insufficient tokens error DIRECT_DEPOSIT_SWAP_FAILED(); /// @dev thrown if payload is not unique error DUPLICATE_PAYLOAD(); /// @dev thrown if native tokens fail to be sent to superform contracts error FAILED_TO_SEND_NATIVE(); /// @dev thrown if allowance is not correct to deposit error INSUFFICIENT_ALLOWANCE_FOR_DEPOSIT(); /// @dev thrown if contract has insufficient balance for operations error INSUFFICIENT_BALANCE(); /// @dev thrown if native amount is not at least equal to the amount in the request error INSUFFICIENT_NATIVE_AMOUNT(); /// @dev thrown if payload cannot be decoded error INVALID_PAYLOAD(); /// @dev thrown if payload status is invalid error INVALID_PAYLOAD_STATUS(); /// @dev thrown if payload type is invalid error INVALID_PAYLOAD_TYPE(); /// LIQUIDITY BRIDGE EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if we try to decode the final swap output token in a xChain liquidity bridging action error CANNOT_DECODE_FINAL_SWAP_OUTPUT_TOKEN(); /// @dev thrown if liquidity bridge fails for erc20 or native tokens error FAILED_TO_EXECUTE_TXDATA(address token); /// @dev thrown if asset being used for deposit mismatches in multivault deposits error INVALID_DEPOSIT_TOKEN(); /// STATE REGISTRY EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if bridge tokens haven't arrived to destination error BRIDGE_TOKENS_PENDING(); /// @dev thrown if withdrawal tx data cannot be updated error CANNOT_UPDATE_WITHDRAW_TX_DATA(); /// @dev thrown if rescue passed dispute deadline error DISPUTE_TIME_ELAPSED(); /// @dev thrown if message failed to reach the specified level of quorum needed error INSUFFICIENT_QUORUM(); /// @dev thrown if broadcast payload is invalid error INVALID_BROADCAST_PAYLOAD(); /// @dev thrown if broadcast fee is invalid error INVALID_BROADCAST_FEE(); /// @dev thrown if retry fees is less than required error INVALID_RETRY_FEE(); /// @dev thrown if broadcast message type is wrong error INVALID_MESSAGE_TYPE(); /// @dev thrown if payload hash is invalid during `retryMessage` on Layezero implementation error INVALID_PAYLOAD_HASH(); /// @dev thrown if update payload function was called on a wrong payload error INVALID_PAYLOAD_UPDATE_REQUEST(); /// @dev thrown if a state registry id is 0 error INVALID_REGISTRY_ID(); /// @dev thrown if a form state registry id is 0 error INVALID_FORM_REGISTRY_ID(); /// @dev thrown if trying to finalize the payload but the withdraw is still locked error LOCKED(); /// @dev thrown if payload is already updated (during xChain deposits) error PAYLOAD_ALREADY_UPDATED(); /// @dev thrown if payload is already processed error PAYLOAD_ALREADY_PROCESSED(); /// @dev thrown if payload is not in UPDATED state error PAYLOAD_NOT_UPDATED(); /// @dev thrown if rescue is still in timelocked state error RESCUE_LOCKED(); /// @dev thrown if rescue is already proposed error RESCUE_ALREADY_PROPOSED(); /// @dev thrown if payload hash is zero during `retryMessage` on Layezero implementation error ZERO_PAYLOAD_HASH(); /// DST SWAPPER EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if process dst swap is tried for processed payload id error DST_SWAP_ALREADY_PROCESSED(); /// @dev thrown if indices have duplicates error DUPLICATE_INDEX(); /// @dev thrown if failed dst swap is already updated error FAILED_DST_SWAP_ALREADY_UPDATED(); /// @dev thrown if indices are out of bounds error INDEX_OUT_OF_BOUNDS(); /// @dev thrown if failed swap token amount is 0 error INVALID_DST_SWAPPER_FAILED_SWAP(); /// @dev thrown if failed swap token amount is not 0 and if token balance is less than amount (non zero) error INVALID_DST_SWAPPER_FAILED_SWAP_NO_TOKEN_BALANCE(); /// @dev thrown if failed swap token amount is not 0 and if native amount is less than amount (non zero) error INVALID_DST_SWAPPER_FAILED_SWAP_NO_NATIVE_BALANCE(); /// @dev forbid xChain deposits with destination swaps without interim token set (for user protection) error INVALID_INTERIM_TOKEN(); /// @dev thrown if dst swap output is less than minimum expected error INVALID_SWAP_OUTPUT(); /// FORM EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if try to forward 4626 share from the superform error CANNOT_FORWARD_4646_TOKEN(); /// @dev thrown in KYCDAO form if no KYC token is present error NO_VALID_KYC_TOKEN(); /// @dev thrown in forms where a certain functionality is not allowed or implemented error NOT_IMPLEMENTED(); /// @dev thrown if form implementation is PAUSED, users cannot perform any action error PAUSED(); /// @dev thrown if shares != deposit output or assets != redeem output when minting SuperPositions error VAULT_IMPLEMENTATION_FAILED(); /// @dev thrown if withdrawal tx data is not updated error WITHDRAW_TOKEN_NOT_UPDATED(); /// @dev thrown if withdrawal tx data is not updated error WITHDRAW_TX_DATA_NOT_UPDATED(); /// @dev thrown when redeeming from vault yields zero collateral error WITHDRAW_ZERO_COLLATERAL(); /// PAYMENT HELPER EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if chainlink is reporting an improper price error CHAINLINK_MALFUNCTION(); /// @dev thrown if chainlink is reporting an incomplete round error CHAINLINK_INCOMPLETE_ROUND(); /// @dev thrown if feed decimals is not 8 error CHAINLINK_UNSUPPORTED_DECIMAL(); /// EMERGENCY QUEUE EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if emergency withdraw is not queued error EMERGENCY_WITHDRAW_NOT_QUEUED(); /// @dev thrown if emergency withdraw is already processed error EMERGENCY_WITHDRAW_PROCESSED_ALREADY(); /// SUPERPOSITION EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if uri cannot be updated error DYNAMIC_URI_FROZEN(); /// @dev thrown if tx history is not found while state sync error TX_HISTORY_NOT_FOUND(); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { Error } from "src/libraries/Error.sol"; library DataLib { function packTxInfo( uint8 txType_, uint8 callbackType_, uint8 multi_, uint8 registryId_, address srcSender_, uint64 srcChainId_ ) internal pure returns (uint256 txInfo) { txInfo = uint256(txType_); txInfo |= uint256(callbackType_) << 8; txInfo |= uint256(multi_) << 16; txInfo |= uint256(registryId_) << 24; txInfo |= uint256(uint160(srcSender_)) << 32; txInfo |= uint256(srcChainId_) << 192; } function decodeTxInfo(uint256 txInfo_) internal pure returns (uint8 txType, uint8 callbackType, uint8 multi, uint8 registryId, address srcSender, uint64 srcChainId) { txType = uint8(txInfo_); callbackType = uint8(txInfo_ >> 8); multi = uint8(txInfo_ >> 16); registryId = uint8(txInfo_ >> 24); srcSender = address(uint160(txInfo_ >> 32)); srcChainId = uint64(txInfo_ >> 192); } /// @dev returns the vault-form-chain pair of a superform /// @param superformId_ is the id of the superform /// @return superform_ is the address of the superform /// @return formImplementationId_ is the form id /// @return chainId_ is the chain id function getSuperform(uint256 superformId_) internal pure returns (address superform_, uint32 formImplementationId_, uint64 chainId_) { superform_ = address(uint160(superformId_)); formImplementationId_ = uint32(superformId_ >> 160); chainId_ = uint64(superformId_ >> 192); if (chainId_ == 0) { revert Error.INVALID_CHAIN_ID(); } } /// @dev returns the vault-form-chain pair of an array of superforms /// @param superformIds_ array of superforms /// @return superforms_ are the address of the vaults function getSuperforms(uint256[] memory superformIds_) internal pure returns (address[] memory superforms_) { uint256 len = superformIds_.length; superforms_ = new address[](len); for (uint256 i; i < len; ++i) { (superforms_[i],,) = getSuperform(superformIds_[i]); } } /// @dev returns the destination chain of a given superform /// @param superformId_ is the id of the superform /// @return chainId_ is the chain id function getDestinationChain(uint256 superformId_) internal pure returns (uint64 chainId_) { chainId_ = uint64(superformId_ >> 192); if (chainId_ == 0) { revert Error.INVALID_CHAIN_ID(); } } /// @dev generates the superformId /// @param superform_ is the address of the superform /// @param formImplementationId_ is the type of the form /// @param chainId_ is the chain id on which the superform is deployed function packSuperform( address superform_, uint32 formImplementationId_, uint64 chainId_ ) internal pure returns (uint256 superformId_) { superformId_ = uint256(uint160(superform_)); superformId_ |= uint256(formImplementationId_) << 160; superformId_ |= uint256(chainId_) << 192; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { AMBMessage } from "src/types/DataTypes.sol"; /// @dev generates proof for amb message and bytes encoded message library ProofLib { function computeProof(AMBMessage memory message_) internal pure returns (bytes32) { return keccak256(abi.encode(message_)); } function computeProofBytes(AMBMessage memory message_) internal pure returns (bytes memory) { return abi.encode(keccak256(abi.encode(message_))); } function computeProof(bytes memory message_) internal pure returns (bytes32) { return keccak256(message_); } function computeProofBytes(bytes memory message_) internal pure returns (bytes memory) { return abi.encode(keccak256(message_)); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { InitSingleVaultData, InitMultiVaultData, LiqRequest } from "src/types/DataTypes.sol"; /// @dev library to cast single values into array for streamlining helper functions /// @notice not gas optimized, suggested for usage only in view/pure functions library ArrayCastLib { function castLiqRequestToArray(LiqRequest memory value_) internal pure returns (LiqRequest[] memory values) { values = new LiqRequest[](1); values[0] = value_; } function castBoolToArray(bool value_) internal pure returns (bool[] memory values) { values = new bool[](1); values[0] = value_; } function castToMultiVaultData(InitSingleVaultData memory data_) internal pure returns (InitMultiVaultData memory castedData_) { uint256[] memory superformIds = new uint256[](1); superformIds[0] = data_.superformId; uint256[] memory amounts = new uint256[](1); amounts[0] = data_.amount; uint256[] memory outputAmounts = new uint256[](1); outputAmounts[0] = data_.outputAmount; uint256[] memory maxSlippage = new uint256[](1); maxSlippage[0] = data_.maxSlippage; LiqRequest[] memory liqData = new LiqRequest[](1); liqData[0] = data_.liqData; castedData_ = InitMultiVaultData( data_.payloadId, superformIds, amounts, outputAmounts, maxSlippage, liqData, castBoolToArray(data_.hasDstSwap), castBoolToArray(data_.retain4626), data_.receiverAddress, data_.extraFormData ); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; /// @dev contains all the common struct and enums used for data communication between chains. /// @dev There are two transaction types in Superform Protocol enum TransactionType { DEPOSIT, WITHDRAW } /// @dev Message types can be INIT, RETURN (for successful Deposits) and FAIL (for failed withdraws) enum CallbackType { INIT, RETURN, FAIL } /// @dev Payloads are stored, updated (deposits) or processed (finalized) enum PayloadState { STORED, UPDATED, PROCESSED } /// @dev contains all the common struct used for interchain token transfers. struct LiqRequest { /// @dev generated data bytes txData; /// @dev input token for deposits, desired output token on target liqDstChainId for withdraws. Must be set for /// txData to be updated on destination for withdraws address token; /// @dev intermediary token on destination. Relevant for xChain deposits where a destination swap is needed for /// validation purposes address interimToken; /// @dev what bridge to use to move tokens uint8 bridgeId; /// @dev dstChainId = liqDstchainId for deposits. For withdraws it is the target chain id for where the underlying /// is to be delivered uint64 liqDstChainId; /// @dev currently this amount is used as msg.value in the txData call. uint256 nativeAmount; } /// @dev main struct that holds required multi vault data for an action struct MultiVaultSFData { // superformids must have same destination. Can have different underlyings uint256[] superformIds; uint256[] amounts; // on deposits, amount of token to deposit on dst, on withdrawals, superpositions to burn uint256[] outputAmounts; // on deposits, amount of shares to receive, on withdrawals, amount of assets to receive uint256[] maxSlippages; LiqRequest[] liqRequests; // if length = 1; amount = sum(amounts) | else amounts must match the amounts being sent bytes permit2data; bool[] hasDstSwaps; bool[] retain4626s; // if true, we don't mint SuperPositions, and send the 4626 back to the user instead address receiverAddress; /// this address must always be an EOA otherwise funds may be lost address receiverAddressSP; /// this address can be a EOA or a contract that implements onERC1155Receiver. must always be set for deposits bytes extraFormData; // extraFormData } /// @dev main struct that holds required single vault data for an action struct SingleVaultSFData { // superformids must have same destination. Can have different underlyings uint256 superformId; uint256 amount; uint256 outputAmount; // on deposits, amount of shares to receive, on withdrawals, amount of assets to receive uint256 maxSlippage; LiqRequest liqRequest; // if length = 1; amount = sum(amounts)| else amounts must match the amounts being sent bytes permit2data; bool hasDstSwap; bool retain4626; // if true, we don't mint SuperPositions, and send the 4626 back to the user instead address receiverAddress; /// this address must always be an EOA otherwise funds may be lost address receiverAddressSP; /// this address can be a EOA or a contract that implements onERC1155Receiver. must always be set for deposits bytes extraFormData; // extraFormData } /// @dev overarching struct for multiDst requests with multi vaults struct MultiDstMultiVaultStateReq { uint8[][] ambIds; uint64[] dstChainIds; MultiVaultSFData[] superformsData; } /// @dev overarching struct for single cross chain requests with multi vaults struct SingleXChainMultiVaultStateReq { uint8[] ambIds; uint64 dstChainId; MultiVaultSFData superformsData; } /// @dev overarching struct for multiDst requests with single vaults struct MultiDstSingleVaultStateReq { uint8[][] ambIds; uint64[] dstChainIds; SingleVaultSFData[] superformsData; } /// @dev overarching struct for single cross chain requests with single vaults struct SingleXChainSingleVaultStateReq { uint8[] ambIds; uint64 dstChainId; SingleVaultSFData superformData; } /// @dev overarching struct for single direct chain requests with single vaults struct SingleDirectSingleVaultStateReq { SingleVaultSFData superformData; } /// @dev overarching struct for single direct chain requests with multi vaults struct SingleDirectMultiVaultStateReq { MultiVaultSFData superformData; } /// @dev struct for SuperRouter with re-arranged data for the message (contains the payloadId) /// @dev realize that receiverAddressSP is not passed, only needed on source chain to mint struct InitMultiVaultData { uint256 payloadId; uint256[] superformIds; uint256[] amounts; uint256[] outputAmounts; uint256[] maxSlippages; LiqRequest[] liqData; bool[] hasDstSwaps; bool[] retain4626s; address receiverAddress; bytes extraFormData; } /// @dev struct for SuperRouter with re-arranged data for the message (contains the payloadId) struct InitSingleVaultData { uint256 payloadId; uint256 superformId; uint256 amount; uint256 outputAmount; uint256 maxSlippage; LiqRequest liqData; bool hasDstSwap; bool retain4626; address receiverAddress; bytes extraFormData; } /// @dev struct for Emergency Queue struct QueuedWithdrawal { address receiverAddress; uint256 superformId; uint256 amount; uint256 srcPayloadId; bool isProcessed; } /// @dev all statuses of the timelock payload enum TimelockStatus { UNAVAILABLE, PENDING, PROCESSED } /// @dev holds information about the timelock payload struct TimelockPayload { uint8 isXChain; uint64 srcChainId; uint256 lockedTill; InitSingleVaultData data; TimelockStatus status; } /// @dev struct that contains the type of transaction, callback flags and other identification, as well as the vaults /// data in params struct AMBMessage { uint256 txInfo; // tight packing of TransactionType txType, CallbackType flag if multi/single vault, registry id, // srcSender and srcChainId bytes params; // decoding txInfo will point to the right datatype of params. Refer PayloadHelper.sol } /// @dev struct that contains the information required for broadcasting changes struct BroadcastMessage { bytes target; bytes32 messageType; bytes message; } /// @dev struct that contains info on returned data from destination struct ReturnMultiData { uint256 payloadId; uint256[] superformIds; uint256[] amounts; } /// @dev struct that contains info on returned data from destination struct ReturnSingleData { uint256 payloadId; uint256 superformId; uint256 amount; } /// @dev struct that contains the data on the fees to pay to the AMBs struct AMBExtraData { uint256[] gasPerAMB; bytes[] extraDataPerAMB; } /// @dev struct that contains the data on the fees to pay to the AMBs on broadcasts struct BroadCastAMBExtraData { uint256[] gasPerDst; bytes[] extraDataPerDst; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData(uint80 _roundId) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
{ "remappings": [ "solmate/=lib/ERC1155A/lib/solmate/src/", "ERC1155A/=lib/ERC1155A/src/", "@openzeppelin/contracts/=lib/ERC1155A/lib/openzeppelin-contracts/contracts/", "ds-test/=lib/ds-test/src/", "erc4626-tests/=lib/ERC1155A/lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/ERC1155A/lib/openzeppelin-contracts/", "pigeon/=lib/pigeon/src/", "solady/=lib/pigeon/lib/solady/", "super-vaults/=lib/super-vaults/src/", "v2-core/=lib/super-vaults/lib/v2-core/contracts/", "v2-periphery/=lib/super-vaults/lib/v2-periphery/contracts/", "v3-core/=lib/super-vaults/lib/v3-core/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"superRegistry_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ARRAY_LENGTH_MISMATCH","type":"error"},{"inputs":[],"name":"BLOCK_CHAIN_ID_OUT_OF_BOUNDS","type":"error"},{"inputs":[],"name":"CHAINLINK_INCOMPLETE_ROUND","type":"error"},{"inputs":[],"name":"CHAINLINK_MALFUNCTION","type":"error"},{"inputs":[],"name":"CHAINLINK_UNSUPPORTED_DECIMAL","type":"error"},{"inputs":[],"name":"INVALID_CHAIN_ID","type":"error"},{"inputs":[],"name":"INVALID_NATIVE_TOKEN_PRICE","type":"error"},{"inputs":[],"name":"INVALID_PAYLOAD_ID","type":"error"},{"inputs":[],"name":"NOT_PAYMENT_ADMIN","type":"error"},{"inputs":[],"name":"NOT_PROTOCOL_ADMIN","type":"error"},{"inputs":[],"name":"ZERO_ADDRESS","type":"error"},{"inputs":[],"name":"ZERO_INPUT_VALUE","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"chainId_","type":"uint64"},{"components":[{"internalType":"address","name":"nativeFeedOracle","type":"address"},{"internalType":"address","name":"gasPriceOracle","type":"address"},{"internalType":"uint256","name":"swapGasUsed","type":"uint256"},{"internalType":"uint256","name":"updateDepositGasUsed","type":"uint256"},{"internalType":"uint256","name":"depositGasUsed","type":"uint256"},{"internalType":"uint256","name":"withdrawGasUsed","type":"uint256"},{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"},{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"},{"internalType":"uint256","name":"dstGasPerByte","type":"uint256"},{"internalType":"uint256","name":"ackGasCost","type":"uint256"},{"internalType":"uint256","name":"timelockCost","type":"uint256"},{"internalType":"uint256","name":"emergencyCost","type":"uint256"},{"internalType":"uint256","name":"updateWithdrawGasUsed","type":"uint256"}],"indexed":false,"internalType":"struct IPaymentHelperV2.PaymentHelperConfig","name":"config_","type":"tuple"}],"name":"ChainConfigAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId_","type":"uint64"},{"indexed":true,"internalType":"uint256","name":"configType_","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"config_","type":"bytes"}],"name":"ChainConfigUpdated","type":"event"},{"inputs":[],"name":"CHAIN_ID","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"ackGasCost","outputs":[{"internalType":"uint256","name":"gasForAck","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId_","type":"uint64"},{"components":[{"internalType":"address","name":"nativeFeedOracle","type":"address"},{"internalType":"address","name":"gasPriceOracle","type":"address"},{"internalType":"uint256","name":"swapGasUsed","type":"uint256"},{"internalType":"uint256","name":"updateDepositGasUsed","type":"uint256"},{"internalType":"uint256","name":"depositGasUsed","type":"uint256"},{"internalType":"uint256","name":"withdrawGasUsed","type":"uint256"},{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"},{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"},{"internalType":"uint256","name":"dstGasPerByte","type":"uint256"},{"internalType":"uint256","name":"ackGasCost","type":"uint256"},{"internalType":"uint256","name":"timelockCost","type":"uint256"},{"internalType":"uint256","name":"emergencyCost","type":"uint256"},{"internalType":"uint256","name":"updateWithdrawGasUsed","type":"uint256"}],"internalType":"struct IPaymentHelperV2.PaymentHelperConfig","name":"config_","type":"tuple"}],"name":"addRemoteChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"chainIds_","type":"uint64[]"},{"components":[{"internalType":"address","name":"nativeFeedOracle","type":"address"},{"internalType":"address","name":"gasPriceOracle","type":"address"},{"internalType":"uint256","name":"swapGasUsed","type":"uint256"},{"internalType":"uint256","name":"updateDepositGasUsed","type":"uint256"},{"internalType":"uint256","name":"depositGasUsed","type":"uint256"},{"internalType":"uint256","name":"withdrawGasUsed","type":"uint256"},{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"},{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"},{"internalType":"uint256","name":"dstGasPerByte","type":"uint256"},{"internalType":"uint256","name":"ackGasCost","type":"uint256"},{"internalType":"uint256","name":"timelockCost","type":"uint256"},{"internalType":"uint256","name":"emergencyCost","type":"uint256"},{"internalType":"uint256","name":"updateWithdrawGasUsed","type":"uint256"}],"internalType":"struct IPaymentHelperV2.PaymentHelperConfig[]","name":"configs_","type":"tuple[]"}],"name":"addRemoteChains","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId_","type":"uint64"},{"internalType":"uint256[]","name":"configTypes_","type":"uint256[]"},{"internalType":"bytes[]","name":"configs_","type":"bytes[]"}],"name":"batchUpdateRemoteChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"chainIds_","type":"uint64[]"},{"internalType":"uint256[][]","name":"configTypes_","type":"uint256[][]"},{"internalType":"bytes[][]","name":"configs_","type":"bytes[][]"}],"name":"batchUpdateRemoteChains","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"dstChainId_","type":"uint64"},{"internalType":"uint8[]","name":"ambIds_","type":"uint8[]"},{"internalType":"bytes","name":"message_","type":"bytes"}],"name":"calculateAMBData","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"depositGasUsed","outputs":[{"internalType":"uint256","name":"gasForDeposit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"emergencyCost","outputs":[{"internalType":"uint256","name":"gasForEmergency","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"ambIds_","type":"uint8[]"},{"internalType":"uint64","name":"dstChainId_","type":"uint64"},{"internalType":"bytes","name":"message_","type":"bytes"},{"internalType":"bytes[]","name":"extraData_","type":"bytes[]"}],"name":"estimateAMBFees","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"payloadId_","type":"uint256"}],"name":"estimateAckCost","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"multi","type":"bool"},{"internalType":"uint8[]","name":"ackAmbIds","type":"uint8[]"},{"internalType":"uint64","name":"srcChainId","type":"uint64"}],"name":"estimateAckCostDefault","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"multi","type":"bool"},{"internalType":"uint8[]","name":"ackAmbIds","type":"uint8[]"},{"internalType":"uint64","name":"srcChainId","type":"uint64"}],"name":"estimateAckCostDefaultNativeSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[][]","name":"ambIds","type":"uint8[][]"},{"internalType":"uint64[]","name":"dstChainIds","type":"uint64[]"},{"components":[{"internalType":"uint256[]","name":"superformIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"outputAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maxSlippages","type":"uint256[]"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest[]","name":"liqRequests","type":"tuple[]"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool[]","name":"hasDstSwaps","type":"bool[]"},{"internalType":"bool[]","name":"retain4626s","type":"bool[]"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct MultiVaultSFData[]","name":"superformsData","type":"tuple[]"}],"internalType":"struct MultiDstMultiVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateMultiDstMultiVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[][]","name":"ambIds","type":"uint8[][]"},{"internalType":"uint64[]","name":"dstChainIds","type":"uint64[]"},{"components":[{"internalType":"uint256","name":"superformId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"maxSlippage","type":"uint256"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest","name":"liqRequest","type":"tuple"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool","name":"hasDstSwap","type":"bool"},{"internalType":"bool","name":"retain4626","type":"bool"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct SingleVaultSFData[]","name":"superformsData","type":"tuple[]"}],"internalType":"struct MultiDstSingleVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateMultiDstSingleVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint256[]","name":"superformIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"outputAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maxSlippages","type":"uint256[]"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest[]","name":"liqRequests","type":"tuple[]"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool[]","name":"hasDstSwaps","type":"bool[]"},{"internalType":"bool[]","name":"retain4626s","type":"bool[]"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct MultiVaultSFData","name":"superformData","type":"tuple"}],"internalType":"struct SingleDirectMultiVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleDirectMultiVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"dstOrSameChainAmt","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"superformId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"maxSlippage","type":"uint256"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest","name":"liqRequest","type":"tuple"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool","name":"hasDstSwap","type":"bool"},{"internalType":"bool","name":"retain4626","type":"bool"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct SingleVaultSFData","name":"superformData","type":"tuple"}],"internalType":"struct SingleDirectSingleVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleDirectSingleVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"dstOrSameChainAmt","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[]","name":"ambIds","type":"uint8[]"},{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"components":[{"internalType":"uint256[]","name":"superformIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"outputAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"maxSlippages","type":"uint256[]"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest[]","name":"liqRequests","type":"tuple[]"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool[]","name":"hasDstSwaps","type":"bool[]"},{"internalType":"bool[]","name":"retain4626s","type":"bool[]"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct MultiVaultSFData","name":"superformsData","type":"tuple"}],"internalType":"struct SingleXChainMultiVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleXChainMultiVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint8[]","name":"ambIds","type":"uint8[]"},{"internalType":"uint64","name":"dstChainId","type":"uint64"},{"components":[{"internalType":"uint256","name":"superformId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"maxSlippage","type":"uint256"},{"components":[{"internalType":"bytes","name":"txData","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"interimToken","type":"address"},{"internalType":"uint8","name":"bridgeId","type":"uint8"},{"internalType":"uint64","name":"liqDstChainId","type":"uint64"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"}],"internalType":"struct LiqRequest","name":"liqRequest","type":"tuple"},{"internalType":"bytes","name":"permit2data","type":"bytes"},{"internalType":"bool","name":"hasDstSwap","type":"bool"},{"internalType":"bool","name":"retain4626","type":"bool"},{"internalType":"address","name":"receiverAddress","type":"address"},{"internalType":"address","name":"receiverAddressSP","type":"address"},{"internalType":"bytes","name":"extraFormData","type":"bytes"}],"internalType":"struct SingleVaultSFData","name":"superformData","type":"tuple"}],"internalType":"struct SingleXChainSingleVaultStateReq","name":"req_","type":"tuple"},{"internalType":"bool","name":"isDeposit_","type":"bool"}],"name":"estimateSingleXChainSingleVault","outputs":[{"internalType":"uint256","name":"liqAmount","type":"uint256"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extraDataForTransmuter","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"gasPerByte","outputs":[{"internalType":"uint256","name":"gasPerByte","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"gasPrice","outputs":[{"internalType":"uint256","name":"defaultGasPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"gasPriceOracle","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegisterTransmuterAMBData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"nativeFeedOracle","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"nativePrice","outputs":[{"internalType":"uint256","name":"defaultNativePrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"superRegistry","outputs":[{"internalType":"contract ISuperRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"swapGasUsed","outputs":[{"internalType":"uint256","name":"gasForSwap","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"timelockCost","outputs":[{"internalType":"uint256","name":"gasForTimelock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"updateDepositGasUsed","outputs":[{"internalType":"uint256","name":"gasForUpdateDeposit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"extraDataForTransmuter_","type":"bytes"}],"name":"updateRegisterAERC20Params","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId_","type":"uint64"},{"internalType":"uint256","name":"configType_","type":"uint256"},{"internalType":"bytes","name":"config_","type":"bytes"}],"name":"updateRemoteChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"updateWithdrawGasUsed","outputs":[{"internalType":"uint256","name":"gasForUpdateWithdraw","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"withdrawGasUsed","outputs":[{"internalType":"uint256","name":"gasForWithdraw","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162005f6f38038062005f6f8339810160408190526200003491620000a4565b6001600160a01b0381166200005c5760405163538ba4f960e01b815260040160405180910390fd5b6001600160401b034611156200008557604051637ecdf93360e01b815260040160405180910390fd5b6001600160401b03461660a0526001600160a01b0316608052620000d6565b600060208284031215620000b757600080fd5b81516001600160a01b0381168114620000cf57600080fd5b9392505050565b60805160a051615de06200018f600039600081816104a7015281816106600152818161110c01528181611f98015281816121cf015281816124810152818161271401528181613282015281816138a2015281816138e40152818161396c0152613c710152600081816102e50152818161069a015281816108b50152818161124901528181611590015281816116cd01528181611bcf0152818161220b015281816124bd0152818161265e01526134f00152615de06000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80637abae2511161011a578063b9694b52116100ad578063d8bb4f4e1161007c578063d8bb4f4e146105a6578063da163637146105c6578063ea7a8392146105ce578063f3afdd88146105e1578063f3d80846146105f457600080fd5b8063b9694b521461055a578063c2085f461461056d578063c97c55b014610580578063d70139741461059357600080fd5b80639d57d64e116100e95780639d57d64e14610501578063a8a0838914610514578063a9ce464814610527578063b1752d591461054757600080fd5b80637abae2511461046d5780637f7aecb51461048257806385e1f4d0146104a2578063904b1a28146104e157600080fd5b80634545fc311161019d57806353d69edc1161016c57806353d69edc146103c4578063596703e7146103d957806361d26cae146103ec5780637504988b1461041f578063786c69f31461044d57600080fd5b80634545fc311461033b5780634786b4241461035b57806349c3af451461037b5780634c75c0d8146103a457600080fd5b80631f864be3116101d95780631f864be3146102bf57806324c73dda146102e05780633283166a1461030757806336c7fe1d1461032857600080fd5b80630292540b1461020b57806310c5fbe41461023e57806312c4da861461025e5780631f5ae58f1461029f575b600080fd5b61022b6102193660046140cb565b600c6020526000908152604090205481565b6040519081526020015b60405180910390f35b61022b61024c3660046140cb565b60046020526000908152604090205481565b61028761026c3660046140cb565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610235565b61022b6102ad3660046140cb565b600b6020526000908152604090205481565b6102d26102cd3660046142be565b610607565b6040516102359291906143c6565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b61031a610315366004614461565b61082b565b60405161023592919061452c565b61022b610336366004614563565b61088a565b61022b6103493660046140cb565b60076020526000908152604090205481565b61022b6103693660046140cb565b60086020526000908152604090205481565b6102876103893660046140cb565b6001602052600090815260409020546001600160a01b031681565b61022b6103b23660046140cb565b60056020526000908152604090205481565b6103cc610a7b565b60405161023591906145c6565b61022b6103e73660046145d9565b610b0d565b6103ff6103fa36600461460a565b610f28565b604080519485526020850193909352918301526060820152608001610235565b61043261042d36600461466d565b6110c7565b60408051938452602084019290925290820152606001610235565b61022b61045b3660046140cb565b60036020526000908152604090205481565b61048061047b3660046146a2565b611226565b005b61022b6104903660046140cb565b60066020526000908152604090205481565b6104c97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160401b039091168152602001610235565b61022b6104ef3660046140cb565b60096020526000908152604090205481565b61048061050f3660046146fa565b611367565b610480610522366004614794565b6114ab565b61022b6105353660046140cb565b60026020526000908152604090205481565b61022b610555366004614563565b611557565b6104806105683660046147d7565b61156d565b61048061057b36600461480b565b6116aa565b6103ff61058e36600461460a565b6117ef565b6103ff6105a136600461460a565b611963565b61022b6105b43660046140cb565b600a6020526000908152604090205481565b6103cc611b1e565b6104806105dc36600461488d565b611bac565b6103ff6105ef36600461460a565b611dbf565b61043261060236600461466d565b611f53565b835160009060609082816001600160401b03811115610628576106286140e8565b604051908082528060200260200182016040528015610651578160200160208202803683370190505b509050866001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b03161461081f5760005b8281101561081d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8a83815181106106d9576106d9614926565b60200260200101516040518263ffffffff1660e01b8152600401610706919060ff91909116815260200190565b602060405180830381865afa158015610723573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610747919061495c565b6001600160a01b031663ea98b147898989858151811061076957610769614926565b60200260200101516040518463ffffffff1660e01b815260040161078f93929190614979565b602060405180830381865afa1580156107ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d091906149b7565b8282815181106107e2576107e2614926565b60200260200101818152505081818151811061080057610800614926565b60200260200101518561081391906149e6565b9450600101610690565b505b91505094509492505050565b60006060600080600061084089898989612092565b92509250925060405180604001604052808481526020018381525060405160200161086b9190614a35565b60408051601f1981840301815291905290999098509650505050505050565b6000606084156109e95760405163bffc1e1360e01b81526001600160401b03841660048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bffc1e1390602401602060405180830381865afa158015610904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092891906149b7565b90506000816001600160401b03811115610944576109446140e8565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50905060005b828110156109a35760001982828151811061099057610990614926565b6020908102919091010152600101610973565b5060405180606001604052806000198152602001828152602001828152506040516020016109d19190614ab8565b60405160208183030381529060405292505050610a30565b506040805160608082018352600019808352602080840182815293850182815285519182019290925292518385015251828201528251808303909101815260809091019091525b610a7084846040518060400160405280600019815260200185815250604051602001610a5c9190614afb565b6040516020818303038152906040526123bc565b9150505b9392505050565b6060600d8054610a8a90614b20565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab690614b20565b8015610b035780601f10610ad857610100808354040283529160200191610b03565b820191906000526020600020905b815481529060010190602001808311610ae657829003601f168201915b5050505050905090565b604080516101008101825260008082526020820181905291810182905260608082018190526080820181905260a0820183905260c0820183905260e08201526000610b777f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b9050806001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdb91906149b7565b808352841115610bfe576040516355da2ca360e11b815260040160405180910390fd5b6040516336445ffd60e01b8152600481018590526001600160a01b038216906336445ffd90602401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6791906149b7565b602083015260405163361ad42b60e01b8152600481018590526001600160a01b0382169063361ad42b90602401600060405180830381865afa158015610cb1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cd99190810190614b99565b6060830152602082015160c081811c9084015260ff601082901c811660a085015260089190911c166040830181905215610d17575060009392505050565b8160a0015160ff16600103610d8c5760008260600151806020019051810190610d409190614dbd565b60408051606081018252855181526020808401518183015282840151828401529151929350610d7192909101614ab8565b60408051601f19818403018152919052606084015250610df7565b60008260600151806020019051810190610da69190614f46565b60408051606080820183528651808352602085810151818501908152958501519385019384528451908101919091529351848401529051838201528151808403820181526080909301909152840152505b604051636c181b2760e11b8152600481018590526001600160a01b0382169063d830364e90602401600060405180830381865afa158015610e3c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e64919081019061500c565b608083015260408051808201918290526336445ffd60e01b90915260448101859052806001600160a01b0383166336445ffd60648301602060405180830381865afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edb91906149b7565b81526060840151602091820152604051610ef6929101614afb565b60408051601f1981840301815291905260e08301819052608083015160c0840151610f20926123bc565b949350505050565b6000806000806000610f47600080516020615d8b833981519152612645565b6040805160018082528183019092529192506000919060208083019080368337019050509050610f7d6040890160208a016140cb565b81600081518110610f9057610f90614926565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b610fc9613fb8565b815260200190600190039081610fc1579050509050610feb60408b018b61509a565b610ff49061526d565b8160008151811061100757611007614926565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c806000019061103d9190615279565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101859052604081018490526001600160a01b03871660608201528b15156080909101526126d7565b91995097509550876110ae87896149e6565b6110b891906149e6565b94505050505092959194509250565b6000806000806110e4600080516020615d8b833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000008160008151811061113e5761113e614926565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b611177614047565b81526020019060019003908161116f579050509050611196898061509a565b61119f90615548565b816000815181106111b2576111b2614926565b602002602001018190525060606112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b919950909750611218905087896149e6565b955050505050509250925092565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015611298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bc919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a9190615554565b61135757604051633108430360e11b815260040160405180910390fd5b611362838383612c86565b505050565b61137e600080516020615d4b833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa1580156113c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e89190615554565b61140557604051633721555560e21b815260040160405180910390fd5b8260008190036114285760405163021b4ea160e01b815260040160405180910390fd5b80821461144857604051634456f5e960e11b815260040160405180910390fd5b60005b818110156114a35761149b86868381811061146857611468614926565b905060200201602081019061147d91906140cb565b85858481811061148f5761148f614926565b90506101a00201613051565b60010161144b565b505050505050565b6114c2600080516020615d4b833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152c9190615554565b61154957604051633721555560e21b815260040160405180910390fd5b6115538282613051565b5050565b6000610f208261156886868661088a565b613269565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa1580156115df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611603919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561165d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116819190615554565b61169e57604051633108430360e11b815260040160405180910390fd5b600d61155382826155b9565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611740919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561179a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117be9190615554565b6117db57604051633108430360e11b815260040160405180910390fd5b6117e88585858585613305565b5050505050565b600080600080600061180e600080516020615d8b833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090506118446040890160208a016140cb565b8160008151811061185757611857614926565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b611890614047565b8152602001906001900390816118885790505090506118b260408b018b61509a565b6118bb90615548565b816000815181106118ce576118ce614926565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c80600001906119049190615279565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101849052604081018590526001600160a01b03871660608201528b15156080909101526126d7565b6000808080806119766020880188615279565b90509050600080600080611997600080516020615d8b833981519152612645565b9050606060005b86811015611af757611ac46040518060e001604052808381526020018f80602001906119ca9190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611a1f9190615279565b85818110611a2f57611a2f614926565b9050602002810190611a419190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018481526020018f8060400190611a9c9190615279565b611aa591615678565b8152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611ad5868c6149e6565b9a50611ae1858b6149e6565b9950611aed848a6149e6565b985060010161199e565b5089611b03898b6149e6565b611b0d91906149e6565b965050505050505092959194509250565b600d8054611b2b90614b20565b80601f0160208091040260200160405190810160405280929190818152602001828054611b5790614b20565b8015611ba45780601f10611b7957610100808354040283529160200191611ba4565b820191906000526020600020905b815481529060010190602001808311611b8757829003601f168201915b505050505081565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015611c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c42919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc09190615554565b611cdd57604051633108430360e11b815260040160405180910390fd5b846000819003611d005760405163021b4ea160e01b815260040160405180910390fd5b8084148015611d0e57508082145b611d2b57604051634456f5e960e11b815260040160405180910390fd5b60005b81811015611db557611dad888883818110611d4b57611d4b614926565b9050602002016020810190611d6091906140cb565b878784818110611d7257611d72614926565b9050602002810190611d849190615279565b878786818110611d9657611d96614926565b9050602002810190611da89190615279565b613305565b600101611d2e565b5050505050505050565b600080808080611dd26020880188615279565b90509050600080600080611df3600080516020615d8b833981519152612645565b9050606060005b86811015611af757611f206040518060e001604052808381526020018f8060200190611e269190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611e7b9190615279565b85818110611e8b57611e8b614926565b9050602002810190611e9d9190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060400190611ef29190615279565b611efb916156df565b8152602001848152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611f31868c6149e6565b9a50611f3d858b6149e6565b9950611f49848a6149e6565b9850600101611dfa565b600080600080611f70600080516020615d8b833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110611fca57611fca614926565b6001600160401b039290921660209283029190910190910152604080516001808252818301909252600091816020015b612002613fb8565b815260200190600190039081611ffa579050509050612021888061509a565b61202a9061526d565b8160008151811061203d5761203d614926565b60200260200101819052506060806112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b606080600080848060200190518101906120ac9190615746565b9050868682602001516040516020016120c7939291906157d2565b60408051601f1981840301815291815260208381019290925280518883028181018401909252888152889261211d928c92918c9186918291908501908490808284376000920191909152508b92506133df915050565b9350806001600160401b03811115612137576121376140e8565b604051908082528060200260200182016040528015612160578160200160208202803683370190505b509450600060405180604001604052806000198152602001888051906020012060405160200161219291815260200190565b60408051601f198184030181529181529152516121b29190602001614afb565b6040516020818303038152906040529050896001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316146123af5760005b828110156123ad5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8c8c8581811061224a5761224a614926565b905060200201602081019061225f9190615822565b6040516001600160e01b031960e084901b16815260ff9091166004820152602401602060405180830381865afa15801561229d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c1919061495c565b6001600160a01b031663ea98b1478d846000036122fd57876040516020016122e99190614afb565b6040516020818303038152906040526122ff565b855b8a868151811061231157612311614926565b60200260200101516040518463ffffffff1660e01b815260040161233793929190614979565b602060405180830381865afa158015612354573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237891906149b7565b905061238481876149e6565b95508088838151811061239957612399614926565b6020908102919091010152506001016121ff565b505b5050509450945094915050565b8251600090816123cd8587866133df565b90506000848060200190518101906123e59190615746565b90508681602001516040516020016123fe92919061583f565b6040516020818303038152906040528160200181905250600060405180604001604052806000198152602001878051906020012060405160200161244491815260200190565b60408051601f198184030181529181529152516124649190602001614afb565b6040516020818303038152906040529050866001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b03161461263a5760005b848110156126385760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8b84815181106124fc576124fc614926565b60200260200101516040518263ffffffff1660e01b8152600401612529919060ff91909116815260200190565b602060405180830381865afa158015612546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256a919061495c565b6001600160a01b031663ea98b1478a846000036125a657866040516020016125929190614afb565b6040516020818303038152906040526125a8565b855b8886815181106125ba576125ba614926565b60200260200101516040518463ffffffff1660e01b81526004016125e093929190614979565b602060405180830381865afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262191906149b7565b905061262d81886149e6565b9650506001016124b1565b505b505050509392505050565b6040516321f8a72160e01b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa1580156126ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d1919061495c565b92915050565b60008060006127106040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316866020015187600001518151811061275657612756614926565b60200260200101516001600160401b03161415905060008260400181815250506000808760600151511190506000816127b8576127b388608001518960000151815181106127a6576127a6614926565b6020026020010151613642565b6127e2565b6127e288606001518960000151815181106127d5576127d5614926565b602002602001015161371c565b9050826127f0576000612820565b612820886040015189602001518a600001518151811061281257612812614926565b6020026020010151836123bc565b606085015281612831576001612856565b606088015188518151811061284857612848614926565b602002602001015160000151515b6020850152606084015161286a90876149e6565b95506000826128a6576128a189608001518a600001518151811061289057612890614926565b6020026020010151608001516137ac565b6128ca565b60608901518951815181106128bd576128bd614926565b6020026020010151608001515b90508860c0015115612a96576128df8161382c565b6128e990896149e6565b97508315612a915761292089602001518a600001518151811061290e5761290e614926565b60200260200101518660200151613875565b8560400181815161293191906149e6565b905250600083156129a55760005b866020015181101561299f5760608b01518b518151811061296257612962614926565b602002602001015160e00151818151811061297f5761297f614926565b60200260200101516129975761299482615890565b91505b60010161293f565b506129d8565b60808a01518a51815181106129bc576129bc614926565b602002602001015160e001516129d8576129d581615890565b90505b6129e181613898565b6129eb90896149e6565b9750600084612a2957612a248b608001518c6000015181518110612a1157612a11614926565b602002602001015160c001511515613912565b612a4d565b60608b01518b5181518110612a4057612a40614926565b602002602001015160c001515b9050612a7a8b602001518c6000015181518110612a6c57612a6c614926565b60200260200101518261395d565b87604001818151612a8b91906149e6565b90525050505b612beb565b8215612b3b5760005b8560200151811015612b3557612b198a606001518b6000015181518110612ac857612ac8614926565b6020026020010151600001518281518110612ae557612ae5614926565b60200260200101518b602001518c6000015181518110612b0757612b07614926565b60200260200101518c60a00151613a1a565b86604001818151612b2a91906149e6565b905250600101612a9f565b50612ba5565b612b9089608001518a6000015181518110612b5857612b58614926565b6020026020010151600001518a602001518b6000015181518110612b7e57612b7e614926565b60200260200101518b60a00151613a1a565b85604001818151612ba191906149e6565b9052505b8315612beb57612bd689602001518a6000015181518110612bc857612bc8614926565b602002602001015182613b16565b85604001818151612be791906149e6565b9052505b83612bf7576000612c2b565b612c2b8960c001518a602001518b6000015181518110612c1957612c19614926565b60200260200101518760200151613bbe565b85604001818151612c3c91906149e6565b905250602089015189518151612c6f9291908110612c5c57612c5c614926565b6020026020010151866040015186613c0a565b612c7990876149e6565b9799969850505050505050565b81600103612d1f57600081806020019051810190612ca4919061495c565b90506001600160a01b03811615801590612cca57506008612cc482613ccd565b60ff1614155b15612ce8576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038416600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600203612db857600081806020019051810190612d3d919061495c565b90506001600160a01b03811615801590612d6357506008612d5d82613ccd565b60ff1614155b15612d81576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038416600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600303612dee5780806020019051810190612dd491906149b7565b6001600160401b0384166000908152600260205260409020555b81600403612e245780806020019051810190612e0a91906149b7565b6001600160401b0384166000908152600360205260409020555b81600503612e5a5780806020019051810190612e4091906149b7565b6001600160401b0384166000908152600560205260409020555b81600603612e905780806020019051810190612e7691906149b7565b6001600160401b0384166000908152600660205260409020555b81600703612ec65780806020019051810190612eac91906149b7565b6001600160401b0384166000908152600760205260409020555b81600803612efc5780806020019051810190612ee291906149b7565b6001600160401b0384166000908152600860205260409020555b81600903612f325780806020019051810190612f1891906149b7565b6001600160401b0384166000908152600960205260409020555b81600a03612f685780806020019051810190612f4e91906149b7565b6001600160401b0384166000908152600a60205260409020555b81600b03612f9e5780806020019051810190612f8491906149b7565b6001600160401b0384166000908152600b60205260409020555b81600c03612fd45780806020019051810190612fba91906149b7565b6001600160401b0384166000908152600c60205260409020555b81600d0361300a5780806020019051810190612ff091906149b7565b6001600160401b0384166000908152600460205260409020555b81836001600160401b03167fae3dadf141b0383d3b4db666b2fc32179836af27e11a3e8f07c3ef8da82e59308360405161304491906145c6565b60405180910390a3505050565b600061306060208301836158a9565b6001600160a01b0316146130e257600061307d60208301836158a9565b9050600861308a82613ccd565b60ff16146130ab576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038316600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b60006130f460408301602084016158a9565b6001600160a01b03161461317957600061311460408301602084016158a9565b9050600861312182613ccd565b60ff1614613142576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038316600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b6001600160401b0382166000908152600260209081526040808320818501359055600382528083206060850135905560058252808320608085013590556006825280832060a085013590556007825280832060c085013590556008825280832060e08501359055600982528083206101008501359055600a82528083206101208501359055600b82528083206101408501359055600c825280832061016085013590556004909152908190206101808301359055517fdee9f507a37f922d400f1af8b89ddcf4419171e4570e9bc6b83e49659d6a26eb9061325d90849084906158c6565b60405180910390a15050565b60008160000361327b575060006126d1565b60006132a67f0000000000000000000000000000000000000000000000000000000000000000613d31565b6132b09084615992565b9050806000036132c45760009150506126d1565b60006132cf85613d31565b9050806000036132f257604051634c8f99a760e11b815260040160405180910390fd5b6132fc81836159a9565b95945050505050565b8260008190036133285760405163021b4ea160e01b815260040160405180910390fd5b80821461334857604051634456f5e960e11b815260040160405180910390fd5b60005b818110156133d6576133ce8787878481811061336957613369614926565b9050602002013586868581811061338257613382614926565b905060200281019061339491906159cb565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c8692505050565b60010161334b565b50505050505050565b60606000828060200190518101906133f79190615746565b905083816020015160405160200161341092919061583f565b60408051601f1981840301815291815260208381019290925285516001600160401b03881660009081526009845282812054925191939091839161345691879101614afb565b604051602081830303815290604052516134709190615992565b9050600061347f8360a0615992565b9050836001600160401b03811115613499576134996140e8565b6040519080825280602002602001820160405280156134cc57816020015b60608152602001906001900390816134b75790505b50955060005b84811015613635576000816000036134ea57836134ec565b825b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630eff125d8b848151811061352f5761352f614926565b60200260200101516040518263ffffffff1660e01b815260040161355c919060ff91909116815260200190565b602060405180830381865afa158015613579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359d919061495c565b6001600160a01b03166325fc6dd0826040518263ffffffff1660e01b81526004016135ca91815260200190565b600060405180830381865afa1580156135e7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261360f9190810190614b99565b88838151811061362157613621614926565b6020908102919091010152506001016134d2565b5050505050509392505050565b6060600060405180610140016040528061365a613e23565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c00151151581526020018460e00151151581526020018461010001516001600160a01b031681526020018461014001518152506040516020016136d69190615a7e565b60408051601f198184030181528282018252600019835260208381018290529151909350613705929101614afb565b604051602081830303815290604052915050919050565b60606000604051806101400160405280613734613e23565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c0015181526020018460e0015181526020018461010001516001600160a01b031681526020018461014001518152506040516020016136d69190615bb0565b604080516001808252818301909252606091816020015b6040805160c0810182526060808252600060208084018290529383018190529082018190526080820181905260a082015282526000199092019101816137c3579050509050818160008151811061381c5761381c614926565b6020026020010181905250919050565b8051600090815b8181101561386e5783818151811061384d5761384d614926565b602002602001015160a001518361386491906149e6565b9250600101613833565b5050919050565b6001600160401b038216600090815260036020526040812054610a749083615992565b6001600160401b037f0000000000000000000000000000000000000000000000000000000000000000166000908152600a602052604081205481906138dd9084615992565b90506139087f0000000000000000000000000000000000000000000000000000000000000000613ebf565b610a749082615992565b60408051600180825281830190925260609160208083019080368337019050509050818160008151811061394857613948614926565b91151560209283029190910190910152919050565b600080836001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316036139a35760009150506126d1565b825160005b818110156139e3578481815181106139c2576139c2614926565b6020026020010151156139db576139d883615890565b92505b6001016139a8565b50816000036139f7576000925050506126d1565b6001600160401b0385166000908152600260205260409020546132fc9083615992565b600080613a2685613f84565b5060405163596db71760e01b815263ffffffff82166004820152909250600091506001600160a01b0385169063596db71790602401602060405180830381865afa158015613a78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a9c9190615554565b905080158015613ab2575063ffffffff82166002145b15613ae1576001600160401b0385166000908152600b6020526040902054613ada90846149e6565b9250613b0d565b8015613b0d576001600160401b0385166000908152600c6020526040902054613b0a90846149e6565b92505b50509392505050565b8051600090815b81811015613bb657838181518110613b3757613b37614926565b602002602001015160000151516000148015613b83575060006001600160a01b0316848281518110613b6b57613b6b614926565b6020026020010151602001516001600160a01b031614155b15613bae576001600160401b038516600090815260046020526040902054613bab90846149e6565b92505b600101613b1d565b505092915050565b60008084613be4576001600160401b038416600090815260066020526040902054613bfe565b6001600160401b0384166000908152600560205260409020545b9050610a708382615992565b600080613c1685613ebf565b613c209085615992565b905080600003613c34576000915050610a74565b82613c40579050610a74565b6000613c4b86613d31565b613c559083615992565b905080600003613c6a57600092505050610a74565b6000613c957f0000000000000000000000000000000000000000000000000000000000000000613d31565b905080600003613cb857604051634c8f99a760e11b815260040160405180910390fd5b613cc281836159a9565b979650505050505050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d0d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d19190615cc3565b6001600160401b0381166000908152602081905260408120546001600160a01b03168015613e0657806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613db3575060408051601f3d908101601f19168201909252613db091810190615cfa565b60015b15613e065760008413613dd95760405163119d4d6b60e11b815260040160405180910390fd5b81600003613dfa576040516376685d7f60e11b815260040160405180910390fd5b50919695505050505050565b50506001600160401b031660009081526007602052604090205490565b6000613e4e7f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b6001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613eaf91906149b7565b9050613eba81615890565b905090565b6001600160401b0381166000908152600160205260408120546001600160a01b03168015613f6757806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613f41575060408051601f3d908101601f19168201909252613f3e91810190615cfa565b60015b15613f675760008413613dd95760405163119d4d6b60e11b815260040160405180910390fd5b50506001600160401b031660009081526008602052604090205490565b8060a081901c60c082901c6000819003613fb15760405163030042b760e01b815260040160405180910390fd5b9193909250565b604051806101600160405280600081526020016000815260200160008152602001600081526020016140186040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b81526060602082018190526000604083018190528183018190526080830181905260a083015260c09091015290565b604051806101600160405280606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081525090565b6001600160401b03811681146140c857600080fd5b50565b6000602082840312156140dd57600080fd5b8135610a74816140b3565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715614120576141206140e8565b60405290565b60405161014081016001600160401b0381118282101715614120576141206140e8565b60405161016081016001600160401b0381118282101715614120576141206140e8565b604051601f8201601f191681016001600160401b0381118282101715614194576141946140e8565b604052919050565b60006001600160401b038211156141b5576141b56140e8565b5060051b60200190565b60ff811681146140c857600080fd5b600082601f8301126141df57600080fd5b813560206141f46141ef8361419c565b61416c565b8083825260208201915060208460051b87010193508684111561421657600080fd5b602086015b8481101561423b57803561422e816141bf565b835291830191830161421b565b509695505050505050565b60006001600160401b0382111561425f5761425f6140e8565b50601f01601f191660200190565b600082601f83011261427e57600080fd5b813561428c6141ef82614246565b8181528460208386010111156142a157600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080608085870312156142d457600080fd5b84356001600160401b03808211156142eb57600080fd5b6142f7888389016141ce565b9550602091508187013561430a816140b3565b945060408701358181111561431e57600080fd5b61432a89828a0161426d565b94505060608701358181111561433f57600080fd5b8701601f8101891361435057600080fd5b803561435e6141ef8261419c565b81815260059190911b8201840190848101908b83111561437d57600080fd5b8584015b838110156143b5578035868111156143995760008081fd5b6143a78e898389010161426d565b845250918601918601614381565b50989b979a50959850505050505050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b81811015614409578451835293830193918301916001016143ed565b5090979650505050505050565b60008083601f84011261442857600080fd5b5081356001600160401b0381111561443f57600080fd5b6020830191508360208260051b850101111561445a57600080fd5b9250929050565b6000806000806060858703121561447757600080fd5b8435614482816140b3565b935060208501356001600160401b038082111561449e57600080fd5b6144aa88838901614416565b909550935060408701359150808211156144c357600080fd5b506144d08782880161426d565b91505092959194509250565b60005b838110156144f75781810151838201526020016144df565b50506000910152565b600081518084526145188160208601602086016144dc565b601f01601f19169290920160200192915050565b828152604060208201526000610f206040830184614500565b80151581146140c857600080fd5b803561455e81614545565b919050565b60008060006060848603121561457857600080fd5b833561458381614545565b925060208401356001600160401b0381111561459e57600080fd5b6145aa868287016141ce565b92505060408401356145bb816140b3565b809150509250925092565b602081526000610a746020830184614500565b6000602082840312156145eb57600080fd5b5035919050565b60006060828403121561460457600080fd5b50919050565b6000806040838503121561461d57600080fd5b82356001600160401b0381111561463357600080fd5b61463f858286016145f2565b925050602083013561465081614545565b809150509250929050565b60006020828403121561460457600080fd5b6000806040838503121561468057600080fd5b82356001600160401b0381111561469657600080fd5b61463f8582860161465b565b6000806000606084860312156146b757600080fd5b83356146c2816140b3565b92506020840135915060408401356001600160401b038111156146e457600080fd5b6146f08682870161426d565b9150509250925092565b6000806000806040858703121561471057600080fd5b84356001600160401b038082111561472757600080fd5b61473388838901614416565b9096509450602087013591508082111561474c57600080fd5b818701915087601f83011261476057600080fd5b81358181111561476f57600080fd5b8860206101a08302850101111561478557600080fd5b95989497505060200194505050565b6000808284036101c08112156147a957600080fd5b83356147b4816140b3565b92506101a0601f19820112156147c957600080fd5b506020830190509250929050565b6000602082840312156147e957600080fd5b81356001600160401b038111156147ff57600080fd5b610f208482850161426d565b60008060008060006060868803121561482357600080fd5b853561482e816140b3565b945060208601356001600160401b038082111561484a57600080fd5b61485689838a01614416565b9096509450604088013591508082111561486f57600080fd5b5061487c88828901614416565b969995985093965092949392505050565b600080600080600080606087890312156148a657600080fd5b86356001600160401b03808211156148bd57600080fd5b6148c98a838b01614416565b909850965060208901359150808211156148e257600080fd5b6148ee8a838b01614416565b9096509450604089013591508082111561490757600080fd5b5061491489828a01614416565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03811681146140c857600080fd5b805161455e8161493c565b60006020828403121561496e57600080fd5b8151610a748161493c565b6001600160401b038416815260606020820152600061499b6060830185614500565b82810360408401526149ad8185614500565b9695505050505050565b6000602082840312156149c957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156126d1576126d16149d0565b60008151808452602080850194506020840160005b83811015614a2a57815187529582019590820190600101614a0e565b509495945050505050565b600060208083528351604082850152614a5160608501826149f9565b82860151601f198683038101604088015281518084529293509084019183850190600581901b8501860160005b82811015614aaa5784878303018452614a98828751614500565b95880195938801939150600101614a7e565b509998505050505050505050565b60208152815160208201526000602083015160606040840152614ade60808401826149f9565b90506040840151601f198483030160608501526132fc82826149f9565b602081528151602082015260006020830151604080840152610f206060840182614500565b600181811c90821680614b3457607f821691505b60208210810361460457634e487b7160e01b600052602260045260246000fd5b600082601f830112614b6557600080fd5b8151614b736141ef82614246565b818152846020838601011115614b8857600080fd5b610f208260208301602087016144dc565b600060208284031215614bab57600080fd5b81516001600160401b03811115614bc157600080fd5b610f2084828501614b54565b600082601f830112614bde57600080fd5b81516020614bee6141ef8361419c565b8083825260208201915060208460051b870101935086841115614c1057600080fd5b602086015b8481101561423b5780518352918301918301614c15565b600060c08284031215614c3e57600080fd5b614c466140fe565b905081516001600160401b03811115614c5e57600080fd5b614c6a84828501614b54565b8252506020820151614c7b8161493c565b60208201526040820151614c8e8161493c565b60408201526060820151614ca1816141bf565b60608201526080820151614cb4816140b3565b8060808301525060a082015160a082015292915050565b600082601f830112614cdc57600080fd5b81516020614cec6141ef8361419c565b82815260059290921b84018101918181019086841115614d0b57600080fd5b8286015b8481101561423b5780516001600160401b03811115614d2e5760008081fd5b614d3c8986838b0101614c2c565b845250918301918301614d0f565b805161455e81614545565b600082601f830112614d6657600080fd5b81516020614d766141ef8361419c565b8083825260208201915060208460051b870101935086841115614d9857600080fd5b602086015b8481101561423b578051614db081614545565b8352918301918301614d9d565b600060208284031215614dcf57600080fd5b81516001600160401b0380821115614de657600080fd5b908301906101408286031215614dfb57600080fd5b614e03614126565b82518152602083015182811115614e1957600080fd5b614e2587828601614bcd565b602083015250604083015182811115614e3d57600080fd5b614e4987828601614bcd565b604083015250606083015182811115614e6157600080fd5b614e6d87828601614bcd565b606083015250608083015182811115614e8557600080fd5b614e9187828601614bcd565b60808301525060a083015182811115614ea957600080fd5b614eb587828601614ccb565b60a08301525060c083015182811115614ecd57600080fd5b614ed987828601614d55565b60c08301525060e083015182811115614ef157600080fd5b614efd87828601614d55565b60e083015250610100614f11818501614951565b908201526101208381015183811115614f2957600080fd5b614f3588828701614b54565b918301919091525095945050505050565b600060208284031215614f5857600080fd5b81516001600160401b0380821115614f6f57600080fd5b908301906101408286031215614f8457600080fd5b614f8c614126565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015182811115614fca57600080fd5b614fd687828601614c2c565b60a083015250614fe860c08401614d4a565b60c0820152614ff960e08401614d4a565b60e0820152610100614f11818501614951565b6000602080838503121561501f57600080fd5b82516001600160401b0381111561503557600080fd5b8301601f8101851361504657600080fd5b80516150546141ef8261419c565b81815260059190911b8201830190838101908783111561507357600080fd5b928401925b82841015613cc257835161508b816141bf565b82529284019290840190615078565b6000823561015e198336030181126150b157600080fd5b9190910192915050565b803561455e8161493c565b600060c082840312156150d857600080fd5b6150e06140fe565b905081356001600160401b038111156150f857600080fd5b6151048482850161426d565b82525060208201356151158161493c565b602082015260408201356151288161493c565b6040820152606082013561513b816141bf565b6060820152608082013561514e816140b3565b8060808301525060a082013560a082015292915050565b6000610160828403121561517857600080fd5b615180614149565b90508135815260208201356020820152604082013560408201526060820135606082015260808201356001600160401b03808211156151be57600080fd5b6151ca858386016150c6565b608084015260a08401359150808211156151e357600080fd5b6151ef8583860161426d565b60a084015261520060c08501614553565b60c084015261521160e08501614553565b60e084015261010091506152268285016150bb565b82840152610120915061523a8285016150bb565b828401526101409150818401358181111561525457600080fd5b6152608682870161426d565b8385015250505092915050565b60006126d13683615165565b6000808335601e1984360301811261529057600080fd5b8301803591506001600160401b038211156152aa57600080fd5b6020019150600581901b360382131561445a57600080fd5b600082601f8301126152d357600080fd5b813560206152e36141ef8361419c565b8083825260208201915060208460051b87010193508684111561530557600080fd5b602086015b8481101561423b578035835291830191830161530a565b600082601f83011261533257600080fd5b813560206153426141ef8361419c565b82815260059290921b8401810191818101908684111561536157600080fd5b8286015b8481101561423b5780356001600160401b038111156153845760008081fd5b6153928986838b01016150c6565b845250918301918301615365565b600082601f8301126153b157600080fd5b813560206153c16141ef8361419c565b8083825260208201915060208460051b8701019350868411156153e357600080fd5b602086015b8481101561423b5780356153fb81614545565b83529183019183016153e8565b6000610160828403121561541b57600080fd5b615423614149565b905081356001600160401b038082111561543c57600080fd5b615448858386016152c2565b8352602084013591508082111561545e57600080fd5b61546a858386016152c2565b6020840152604084013591508082111561548357600080fd5b61548f858386016152c2565b604084015260608401359150808211156154a857600080fd5b6154b4858386016152c2565b606084015260808401359150808211156154cd57600080fd5b6154d985838601615321565b608084015260a08401359150808211156154f257600080fd5b6154fe8583860161426d565b60a084015260c084013591508082111561551757600080fd5b615523858386016153a0565b60c084015260e084013591508082111561553c57600080fd5b615211858386016153a0565b60006126d13683615408565b60006020828403121561556657600080fd5b8151610a7481614545565b601f821115611362576000816000526020600020601f850160051c8101602086101561559a5750805b601f850160051c820191505b818110156114a3578281556001016155a6565b81516001600160401b038111156155d2576155d26140e8565b6155e6816155e08454614b20565b84615571565b602080601f83116001811461561b57600084156156035750858301515b600019600386901b1c1916600185901b1785556114a3565b600085815260208120601f198616915b8281101561564a5788860151825594840194600190910190840161562b565b50858210156156685787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006156866141ef8461419c565b80848252602080830192508560051b8501368111156156a457600080fd5b855b81811015613dfa5780356001600160401b038111156156c55760008081fd5b6156d136828a01615165565b8652509382019382016156a6565b60006156ed6141ef8461419c565b80848252602080830192508560051b85013681111561570b57600080fd5b855b81811015613dfa5780356001600160401b0381111561572c5760008081fd5b61573836828a01615408565b86525093820193820161570d565b60006020828403121561575857600080fd5b81516001600160401b038082111561576f57600080fd5b908301906040828603121561578357600080fd5b60405160408101818110838211171561579e5761579e6140e8565b604052825181526020830151828111156157b757600080fd5b6157c387828601614b54565b60208301525095945050505050565b6040808252810183905260008460608301825b8681101561580f5782356157f8816141bf565b60ff168252602092830192909101906001016157e5565b508381036020850152613cc28186614500565b60006020828403121561583457600080fd5b8135610a74816141bf565b604080825283519082018190526000906020906060840190828701845b8281101561587b57815160ff168452928401929084019060010161585c565b5050508381036020850152613b0a8186614500565b6000600182016158a2576158a26149d0565b5060010190565b6000602082840312156158bb57600080fd5b8135610a748161493c565b6001600160401b03831681526101c081016158f4602083016158e7856150bb565b6001600160a01b03169052565b615900602084016150bb565b6001600160a01b0381166040840152506040830135606083015260608301356080830152608083013560a083015260a083013560c083015260c083013560e083015261010060e0840135818401526101208185013581850152610140915080850135828501525061016081850135818501526101809150808501358285015250808401356101a0840152509392505050565b80820281158282048414176126d1576126d16149d0565b6000826159c657634e487b7160e01b600052601260045260246000fd5b500490565b6000808335601e198436030181126159e257600080fd5b8301803591506001600160401b038211156159fc57600080fd5b60200191503681900382131561445a57600080fd5b6000815160c08452615a2660c0850182614500565b9050602083015160018060a01b038082166020870152806040860151166040870152505060ff60608401511660608501526001600160401b03608084015116608085015260a083015160a08501528091505092915050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a08301516101408060c0850152615acf610160850183615a11565b915060c0850151615ae460e086018215159052565b5060e0850151610100615afa8187018315159052565b8601519050610120615b16868201836001600160a01b03169052565b860151858403601f19018387015290506149ad8382614500565b60008282518085526020808601955060208260051b8401016020860160005b8481101561440957601f19868403018952615b6b838351615a11565b98840198925090830190600101615b4f565b60008151808452602080850194506020840160005b83811015614a2a578151151587529582019590820190600101615b92565b602081528151602082015260006020830151610140806040850152615bd96101608501836149f9565b91506040850151601f1980868503016060870152615bf784836149f9565b93506060870151915080868503016080870152615c1484836149f9565b935060808701519150808685030160a0870152615c3184836149f9565b935060a08701519150808685030160c0870152615c4e8483615b30565b935060c08701519150808685030160e0870152615c6b8483615b7d565b935060e08701519150610100818786030181880152615c8a8584615b7d565b945080880151925050610120615caa818801846001600160a01b03169052565b8701518685039091018387015290506149ad8382614500565b600060208284031215615cd557600080fd5b8151610a74816141bf565b805169ffffffffffffffffffff8116811461455e57600080fd5b600080600080600060a08688031215615d1257600080fd5b615d1b86615ce0565b9450602086015193506040860151925060608601519150615d3e60808701615ce0565b9050929550929590935056fe6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa8684a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db67bcc180fb907e9ae431665de4bc74305c00b7b27442aadd477980ecc4bb14c011a2646970667358221220f9bde5d8b97499d4bda470d0f2b1126f4ac099c2b82dbf857109419d6cad275664736f6c6343000817003300000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102065760003560e01c80637abae2511161011a578063b9694b52116100ad578063d8bb4f4e1161007c578063d8bb4f4e146105a6578063da163637146105c6578063ea7a8392146105ce578063f3afdd88146105e1578063f3d80846146105f457600080fd5b8063b9694b521461055a578063c2085f461461056d578063c97c55b014610580578063d70139741461059357600080fd5b80639d57d64e116100e95780639d57d64e14610501578063a8a0838914610514578063a9ce464814610527578063b1752d591461054757600080fd5b80637abae2511461046d5780637f7aecb51461048257806385e1f4d0146104a2578063904b1a28146104e157600080fd5b80634545fc311161019d57806353d69edc1161016c57806353d69edc146103c4578063596703e7146103d957806361d26cae146103ec5780637504988b1461041f578063786c69f31461044d57600080fd5b80634545fc311461033b5780634786b4241461035b57806349c3af451461037b5780634c75c0d8146103a457600080fd5b80631f864be3116101d95780631f864be3146102bf57806324c73dda146102e05780633283166a1461030757806336c7fe1d1461032857600080fd5b80630292540b1461020b57806310c5fbe41461023e57806312c4da861461025e5780631f5ae58f1461029f575b600080fd5b61022b6102193660046140cb565b600c6020526000908152604090205481565b6040519081526020015b60405180910390f35b61022b61024c3660046140cb565b60046020526000908152604090205481565b61028761026c3660046140cb565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610235565b61022b6102ad3660046140cb565b600b6020526000908152604090205481565b6102d26102cd3660046142be565b610607565b6040516102359291906143c6565b6102877f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a251481565b61031a610315366004614461565b61082b565b60405161023592919061452c565b61022b610336366004614563565b61088a565b61022b6103493660046140cb565b60076020526000908152604090205481565b61022b6103693660046140cb565b60086020526000908152604090205481565b6102876103893660046140cb565b6001602052600090815260409020546001600160a01b031681565b61022b6103b23660046140cb565b60056020526000908152604090205481565b6103cc610a7b565b60405161023591906145c6565b61022b6103e73660046145d9565b610b0d565b6103ff6103fa36600461460a565b610f28565b604080519485526020850193909352918301526060820152608001610235565b61043261042d36600461466d565b6110c7565b60408051938452602084019290925290820152606001610235565b61022b61045b3660046140cb565b60036020526000908152604090205481565b61048061047b3660046146a2565b611226565b005b61022b6104903660046140cb565b60066020526000908152604090205481565b6104c97f000000000000000000000000000000000000000000000000000000000000000181565b6040516001600160401b039091168152602001610235565b61022b6104ef3660046140cb565b60096020526000908152604090205481565b61048061050f3660046146fa565b611367565b610480610522366004614794565b6114ab565b61022b6105353660046140cb565b60026020526000908152604090205481565b61022b610555366004614563565b611557565b6104806105683660046147d7565b61156d565b61048061057b36600461480b565b6116aa565b6103ff61058e36600461460a565b6117ef565b6103ff6105a136600461460a565b611963565b61022b6105b43660046140cb565b600a6020526000908152604090205481565b6103cc611b1e565b6104806105dc36600461488d565b611bac565b6103ff6105ef36600461460a565b611dbf565b61043261060236600461466d565b611f53565b835160009060609082816001600160401b03811115610628576106286140e8565b604051908082528060200260200182016040528015610651578160200160208202803683370190505b509050866001600160401b03167f00000000000000000000000000000000000000000000000000000000000000016001600160401b03161461081f5760005b8281101561081d577f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8a83815181106106d9576106d9614926565b60200260200101516040518263ffffffff1660e01b8152600401610706919060ff91909116815260200190565b602060405180830381865afa158015610723573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610747919061495c565b6001600160a01b031663ea98b147898989858151811061076957610769614926565b60200260200101516040518463ffffffff1660e01b815260040161078f93929190614979565b602060405180830381865afa1580156107ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d091906149b7565b8282815181106107e2576107e2614926565b60200260200101818152505081818151811061080057610800614926565b60200260200101518561081391906149e6565b9450600101610690565b505b91505094509492505050565b60006060600080600061084089898989612092565b92509250925060405180604001604052808481526020018381525060405160200161086b9190614a35565b60408051601f1981840301815291905290999098509650505050505050565b6000606084156109e95760405163bffc1e1360e01b81526001600160401b03841660048201526000907f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b03169063bffc1e1390602401602060405180830381865afa158015610904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092891906149b7565b90506000816001600160401b03811115610944576109446140e8565b60405190808252806020026020018201604052801561096d578160200160208202803683370190505b50905060005b828110156109a35760001982828151811061099057610990614926565b6020908102919091010152600101610973565b5060405180606001604052806000198152602001828152602001828152506040516020016109d19190614ab8565b60405160208183030381529060405292505050610a30565b506040805160608082018352600019808352602080840182815293850182815285519182019290925292518385015251828201528251808303909101815260809091019091525b610a7084846040518060400160405280600019815260200185815250604051602001610a5c9190614afb565b6040516020818303038152906040526123bc565b9150505b9392505050565b6060600d8054610a8a90614b20565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab690614b20565b8015610b035780601f10610ad857610100808354040283529160200191610b03565b820191906000526020600020905b815481529060010190602001808311610ae657829003601f168201915b5050505050905090565b604080516101008101825260008082526020820181905291810182905260608082018190526080820181905260a0820183905260c0820183905260e08201526000610b777f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b9050806001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdb91906149b7565b808352841115610bfe576040516355da2ca360e11b815260040160405180910390fd5b6040516336445ffd60e01b8152600481018590526001600160a01b038216906336445ffd90602401602060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6791906149b7565b602083015260405163361ad42b60e01b8152600481018590526001600160a01b0382169063361ad42b90602401600060405180830381865afa158015610cb1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cd99190810190614b99565b6060830152602082015160c081811c9084015260ff601082901c811660a085015260089190911c166040830181905215610d17575060009392505050565b8160a0015160ff16600103610d8c5760008260600151806020019051810190610d409190614dbd565b60408051606081018252855181526020808401518183015282840151828401529151929350610d7192909101614ab8565b60408051601f19818403018152919052606084015250610df7565b60008260600151806020019051810190610da69190614f46565b60408051606080820183528651808352602085810151818501908152958501519385019384528451908101919091529351848401529051838201528151808403820181526080909301909152840152505b604051636c181b2760e11b8152600481018590526001600160a01b0382169063d830364e90602401600060405180830381865afa158015610e3c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e64919081019061500c565b608083015260408051808201918290526336445ffd60e01b90915260448101859052806001600160a01b0383166336445ffd60648301602060405180830381865afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edb91906149b7565b81526060840151602091820152604051610ef6929101614afb565b60408051601f1981840301815291905260e08301819052608083015160c0840151610f20926123bc565b949350505050565b6000806000806000610f47600080516020615d8b833981519152612645565b6040805160018082528183019092529192506000919060208083019080368337019050509050610f7d6040890160208a016140cb565b81600081518110610f9057610f90614926565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b610fc9613fb8565b815260200190600190039081610fc1579050509050610feb60408b018b61509a565b610ff49061526d565b8160008151811061100757611007614926565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c806000019061103d9190615279565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101859052604081018490526001600160a01b03871660608201528b15156080909101526126d7565b91995097509550876110ae87896149e6565b6110b891906149e6565b94505050505092959194509250565b6000806000806110e4600080516020615d8b833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f00000000000000000000000000000000000000000000000000000000000000018160008151811061113e5761113e614926565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b611177614047565b81526020019060019003908161116f579050509050611196898061509a565b61119f90615548565b816000815181106111b2576111b2614926565b602002602001018190525060606112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b919950909750611218905087896149e6565b955050505050509250925092565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015611298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bc919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a9190615554565b61135757604051633108430360e11b815260040160405180910390fd5b611362838383612c86565b505050565b61137e600080516020615d4b833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa1580156113c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e89190615554565b61140557604051633721555560e21b815260040160405180910390fd5b8260008190036114285760405163021b4ea160e01b815260040160405180910390fd5b80821461144857604051634456f5e960e11b815260040160405180910390fd5b60005b818110156114a35761149b86868381811061146857611468614926565b905060200201602081019061147d91906140cb565b85858481811061148f5761148f614926565b90506101a00201613051565b60010161144b565b505050505050565b6114c2600080516020615d4b833981519152612645565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa158015611508573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152c9190615554565b61154957604051633721555560e21b815260040160405180910390fd5b6115538282613051565b5050565b6000610f208261156886868661088a565b613269565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa1580156115df573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611603919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561165d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116819190615554565b61169e57604051633108430360e11b815260040160405180910390fd5b600d61155382826155b9565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611740919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa15801561179a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117be9190615554565b6117db57604051633108430360e11b815260040160405180910390fd5b6117e88585858585613305565b5050505050565b600080600080600061180e600080516020615d8b833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090506118446040890160208a016140cb565b8160008151811061185757611857614926565b6001600160401b03929092166020928302919091018201526040805160018082528183019092526060926000929082015b611890614047565b8152602001906001900390816118885790505090506118b260408b018b61509a565b6118bb90615548565b816000815181106118ce576118ce614926565b602002602001018190525061109c6040518060e00160405280600081526020018581526020018c80600001906119049190615279565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060208101849052604081018590526001600160a01b03871660608201528b15156080909101526126d7565b6000808080806119766020880188615279565b90509050600080600080611997600080516020615d8b833981519152612645565b9050606060005b86811015611af757611ac46040518060e001604052808381526020018f80602001906119ca9190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611a1f9190615279565b85818110611a2f57611a2f614926565b9050602002810190611a419190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018481526020018f8060400190611a9c9190615279565b611aa591615678565b8152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611ad5868c6149e6565b9a50611ae1858b6149e6565b9950611aed848a6149e6565b985060010161199e565b5089611b03898b6149e6565b611b0d91906149e6565b965050505050505092959194509250565b600d8054611b2b90614b20565b80601f0160208091040260200160405190810160405280929190818152602001828054611b5790614b20565b8015611ba45780601f10611b7957610100808354040283529160200191611ba4565b820191906000526020600020905b815481529060010190602001808311611b8757829003601f168201915b505050505081565b6040516321f8a72160e01b8152600080516020615d4b83398151915260048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015611c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c42919061495c565b604051632474521560e21b8152600080516020615d6b83398151915260048201523360248201526001600160a01b0391909116906391d1485490604401602060405180830381865afa158015611c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc09190615554565b611cdd57604051633108430360e11b815260040160405180910390fd5b846000819003611d005760405163021b4ea160e01b815260040160405180910390fd5b8084148015611d0e57508082145b611d2b57604051634456f5e960e11b815260040160405180910390fd5b60005b81811015611db557611dad888883818110611d4b57611d4b614926565b9050602002016020810190611d6091906140cb565b878784818110611d7257611d72614926565b9050602002810190611d849190615279565b878786818110611d9657611d96614926565b9050602002810190611da89190615279565b613305565b600101611d2e565b5050505050505050565b600080808080611dd26020880188615279565b90509050600080600080611df3600080516020615d8b833981519152612645565b9050606060005b86811015611af757611f206040518060e001604052808381526020018f8060200190611e269190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060000190611e7b9190615279565b85818110611e8b57611e8b614926565b9050602002810190611e9d9190615279565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505081526020018f8060400190611ef29190615279565b611efb916156df565b8152602001848152602001856001600160a01b031681526020018e15158152506126d7565b91975095509350611f31868c6149e6565b9a50611f3d858b6149e6565b9950611f49848a6149e6565b9850600101611dfa565b600080600080611f70600080516020615d8b833981519152612645565b60408051600180825281830190925291925060009190602080830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000181600081518110611fca57611fca614926565b6001600160401b039290921660209283029190910190910152604080516001808252818301909252600091816020015b612002613fb8565b815260200190600190039081611ffa579050509050612021888061509a565b61202a9061526d565b8160008151811061203d5761203d614926565b60200260200101819052506060806112066040518060e0016040528060008152602001868152602001838152602001848152602001858152602001876001600160a01b031681526020018b15158152506126d7565b606080600080848060200190518101906120ac9190615746565b9050868682602001516040516020016120c7939291906157d2565b60408051601f1981840301815291815260208381019290925280518883028181018401909252888152889261211d928c92918c9186918291908501908490808284376000920191909152508b92506133df915050565b9350806001600160401b03811115612137576121376140e8565b604051908082528060200260200182016040528015612160578160200160208202803683370190505b509450600060405180604001604052806000198152602001888051906020012060405160200161219291815260200190565b60408051601f198184030181529181529152516121b29190602001614afb565b6040516020818303038152906040529050896001600160401b03167f00000000000000000000000000000000000000000000000000000000000000016001600160401b0316146123af5760005b828110156123ad5760007f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8c8c8581811061224a5761224a614926565b905060200201602081019061225f9190615822565b6040516001600160e01b031960e084901b16815260ff9091166004820152602401602060405180830381865afa15801561229d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c1919061495c565b6001600160a01b031663ea98b1478d846000036122fd57876040516020016122e99190614afb565b6040516020818303038152906040526122ff565b855b8a868151811061231157612311614926565b60200260200101516040518463ffffffff1660e01b815260040161233793929190614979565b602060405180830381865afa158015612354573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237891906149b7565b905061238481876149e6565b95508088838151811061239957612399614926565b6020908102919091010152506001016121ff565b505b5050509450945094915050565b8251600090816123cd8587866133df565b90506000848060200190518101906123e59190615746565b90508681602001516040516020016123fe92919061583f565b6040516020818303038152906040528160200181905250600060405180604001604052806000198152602001878051906020012060405160200161244491815260200190565b60408051601f198184030181529181529152516124649190602001614afb565b6040516020818303038152906040529050866001600160401b03167f00000000000000000000000000000000000000000000000000000000000000016001600160401b03161461263a5760005b848110156126385760007f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8b84815181106124fc576124fc614926565b60200260200101516040518263ffffffff1660e01b8152600401612529919060ff91909116815260200190565b602060405180830381865afa158015612546573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256a919061495c565b6001600160a01b031663ea98b1478a846000036125a657866040516020016125929190614afb565b6040516020818303038152906040526125a8565b855b8886815181106125ba576125ba614926565b60200260200101516040518463ffffffff1660e01b81526004016125e093929190614979565b602060405180830381865afa1580156125fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262191906149b7565b905061262d81886149e6565b9650506001016124b1565b505b505050509392505050565b6040516321f8a72160e01b8152600481018290526000907f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa1580156126ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d1919061495c565b92915050565b60008060006127106040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b60007f00000000000000000000000000000000000000000000000000000000000000016001600160401b0316866020015187600001518151811061275657612756614926565b60200260200101516001600160401b03161415905060008260400181815250506000808760600151511190506000816127b8576127b388608001518960000151815181106127a6576127a6614926565b6020026020010151613642565b6127e2565b6127e288606001518960000151815181106127d5576127d5614926565b602002602001015161371c565b9050826127f0576000612820565b612820886040015189602001518a600001518151811061281257612812614926565b6020026020010151836123bc565b606085015281612831576001612856565b606088015188518151811061284857612848614926565b602002602001015160000151515b6020850152606084015161286a90876149e6565b95506000826128a6576128a189608001518a600001518151811061289057612890614926565b6020026020010151608001516137ac565b6128ca565b60608901518951815181106128bd576128bd614926565b6020026020010151608001515b90508860c0015115612a96576128df8161382c565b6128e990896149e6565b97508315612a915761292089602001518a600001518151811061290e5761290e614926565b60200260200101518660200151613875565b8560400181815161293191906149e6565b905250600083156129a55760005b866020015181101561299f5760608b01518b518151811061296257612962614926565b602002602001015160e00151818151811061297f5761297f614926565b60200260200101516129975761299482615890565b91505b60010161293f565b506129d8565b60808a01518a51815181106129bc576129bc614926565b602002602001015160e001516129d8576129d581615890565b90505b6129e181613898565b6129eb90896149e6565b9750600084612a2957612a248b608001518c6000015181518110612a1157612a11614926565b602002602001015160c001511515613912565b612a4d565b60608b01518b5181518110612a4057612a40614926565b602002602001015160c001515b9050612a7a8b602001518c6000015181518110612a6c57612a6c614926565b60200260200101518261395d565b87604001818151612a8b91906149e6565b90525050505b612beb565b8215612b3b5760005b8560200151811015612b3557612b198a606001518b6000015181518110612ac857612ac8614926565b6020026020010151600001518281518110612ae557612ae5614926565b60200260200101518b602001518c6000015181518110612b0757612b07614926565b60200260200101518c60a00151613a1a565b86604001818151612b2a91906149e6565b905250600101612a9f565b50612ba5565b612b9089608001518a6000015181518110612b5857612b58614926565b6020026020010151600001518a602001518b6000015181518110612b7e57612b7e614926565b60200260200101518b60a00151613a1a565b85604001818151612ba191906149e6565b9052505b8315612beb57612bd689602001518a6000015181518110612bc857612bc8614926565b602002602001015182613b16565b85604001818151612be791906149e6565b9052505b83612bf7576000612c2b565b612c2b8960c001518a602001518b6000015181518110612c1957612c19614926565b60200260200101518760200151613bbe565b85604001818151612c3c91906149e6565b905250602089015189518151612c6f9291908110612c5c57612c5c614926565b6020026020010151866040015186613c0a565b612c7990876149e6565b9799969850505050505050565b81600103612d1f57600081806020019051810190612ca4919061495c565b90506001600160a01b03811615801590612cca57506008612cc482613ccd565b60ff1614155b15612ce8576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038416600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600203612db857600081806020019051810190612d3d919061495c565b90506001600160a01b03811615801590612d6357506008612d5d82613ccd565b60ff1614155b15612d81576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038416600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b81600303612dee5780806020019051810190612dd491906149b7565b6001600160401b0384166000908152600260205260409020555b81600403612e245780806020019051810190612e0a91906149b7565b6001600160401b0384166000908152600360205260409020555b81600503612e5a5780806020019051810190612e4091906149b7565b6001600160401b0384166000908152600560205260409020555b81600603612e905780806020019051810190612e7691906149b7565b6001600160401b0384166000908152600660205260409020555b81600703612ec65780806020019051810190612eac91906149b7565b6001600160401b0384166000908152600760205260409020555b81600803612efc5780806020019051810190612ee291906149b7565b6001600160401b0384166000908152600860205260409020555b81600903612f325780806020019051810190612f1891906149b7565b6001600160401b0384166000908152600960205260409020555b81600a03612f685780806020019051810190612f4e91906149b7565b6001600160401b0384166000908152600a60205260409020555b81600b03612f9e5780806020019051810190612f8491906149b7565b6001600160401b0384166000908152600b60205260409020555b81600c03612fd45780806020019051810190612fba91906149b7565b6001600160401b0384166000908152600c60205260409020555b81600d0361300a5780806020019051810190612ff091906149b7565b6001600160401b0384166000908152600460205260409020555b81836001600160401b03167fae3dadf141b0383d3b4db666b2fc32179836af27e11a3e8f07c3ef8da82e59308360405161304491906145c6565b60405180910390a3505050565b600061306060208301836158a9565b6001600160a01b0316146130e257600061307d60208301836158a9565b9050600861308a82613ccd565b60ff16146130ab576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038316600090815260208190526040902080546001600160a01b0319166001600160a01b03929092169190911790555b60006130f460408301602084016158a9565b6001600160a01b03161461317957600061311460408301602084016158a9565b9050600861312182613ccd565b60ff1614613142576040516333339aa360e11b815260040160405180910390fd5b6001600160401b038316600090815260016020526040902080546001600160a01b0319166001600160a01b03929092169190911790555b6001600160401b0382166000908152600260209081526040808320818501359055600382528083206060850135905560058252808320608085013590556006825280832060a085013590556007825280832060c085013590556008825280832060e08501359055600982528083206101008501359055600a82528083206101208501359055600b82528083206101408501359055600c825280832061016085013590556004909152908190206101808301359055517fdee9f507a37f922d400f1af8b89ddcf4419171e4570e9bc6b83e49659d6a26eb9061325d90849084906158c6565b60405180910390a15050565b60008160000361327b575060006126d1565b60006132a67f0000000000000000000000000000000000000000000000000000000000000001613d31565b6132b09084615992565b9050806000036132c45760009150506126d1565b60006132cf85613d31565b9050806000036132f257604051634c8f99a760e11b815260040160405180910390fd5b6132fc81836159a9565b95945050505050565b8260008190036133285760405163021b4ea160e01b815260040160405180910390fd5b80821461334857604051634456f5e960e11b815260040160405180910390fd5b60005b818110156133d6576133ce8787878481811061336957613369614926565b9050602002013586868581811061338257613382614926565b905060200281019061339491906159cb565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c8692505050565b60010161334b565b50505050505050565b60606000828060200190518101906133f79190615746565b905083816020015160405160200161341092919061583f565b60408051601f1981840301815291815260208381019290925285516001600160401b03881660009081526009845282812054925191939091839161345691879101614afb565b604051602081830303815290604052516134709190615992565b9050600061347f8360a0615992565b9050836001600160401b03811115613499576134996140e8565b6040519080825280602002602001820160405280156134cc57816020015b60608152602001906001900390816134b75790505b50955060005b84811015613635576000816000036134ea57836134ec565b825b90507f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316630eff125d8b848151811061352f5761352f614926565b60200260200101516040518263ffffffff1660e01b815260040161355c919060ff91909116815260200190565b602060405180830381865afa158015613579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359d919061495c565b6001600160a01b03166325fc6dd0826040518263ffffffff1660e01b81526004016135ca91815260200190565b600060405180830381865afa1580156135e7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261360f9190810190614b99565b88838151811061362157613621614926565b6020908102919091010152506001016134d2565b5050505050509392505050565b6060600060405180610140016040528061365a613e23565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c00151151581526020018460e00151151581526020018461010001516001600160a01b031681526020018461014001518152506040516020016136d69190615a7e565b60408051601f198184030181528282018252600019835260208381018290529151909350613705929101614afb565b604051602081830303815290604052915050919050565b60606000604051806101400160405280613734613e23565b815260200184600001518152602001846020015181526020018460400151815260200184606001518152602001846080015181526020018460c0015181526020018460e0015181526020018461010001516001600160a01b031681526020018461014001518152506040516020016136d69190615bb0565b604080516001808252818301909252606091816020015b6040805160c0810182526060808252600060208084018290529383018190529082018190526080820181905260a082015282526000199092019101816137c3579050509050818160008151811061381c5761381c614926565b6020026020010181905250919050565b8051600090815b8181101561386e5783818151811061384d5761384d614926565b602002602001015160a001518361386491906149e6565b9250600101613833565b5050919050565b6001600160401b038216600090815260036020526040812054610a749083615992565b6001600160401b037f0000000000000000000000000000000000000000000000000000000000000001166000908152600a602052604081205481906138dd9084615992565b90506139087f0000000000000000000000000000000000000000000000000000000000000001613ebf565b610a749082615992565b60408051600180825281830190925260609160208083019080368337019050509050818160008151811061394857613948614926565b91151560209283029190910190910152919050565b600080836001600160401b03167f00000000000000000000000000000000000000000000000000000000000000016001600160401b0316036139a35760009150506126d1565b825160005b818110156139e3578481815181106139c2576139c2614926565b6020026020010151156139db576139d883615890565b92505b6001016139a8565b50816000036139f7576000925050506126d1565b6001600160401b0385166000908152600260205260409020546132fc9083615992565b600080613a2685613f84565b5060405163596db71760e01b815263ffffffff82166004820152909250600091506001600160a01b0385169063596db71790602401602060405180830381865afa158015613a78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a9c9190615554565b905080158015613ab2575063ffffffff82166002145b15613ae1576001600160401b0385166000908152600b6020526040902054613ada90846149e6565b9250613b0d565b8015613b0d576001600160401b0385166000908152600c6020526040902054613b0a90846149e6565b92505b50509392505050565b8051600090815b81811015613bb657838181518110613b3757613b37614926565b602002602001015160000151516000148015613b83575060006001600160a01b0316848281518110613b6b57613b6b614926565b6020026020010151602001516001600160a01b031614155b15613bae576001600160401b038516600090815260046020526040902054613bab90846149e6565b92505b600101613b1d565b505092915050565b60008084613be4576001600160401b038416600090815260066020526040902054613bfe565b6001600160401b0384166000908152600560205260409020545b9050610a708382615992565b600080613c1685613ebf565b613c209085615992565b905080600003613c34576000915050610a74565b82613c40579050610a74565b6000613c4b86613d31565b613c559083615992565b905080600003613c6a57600092505050610a74565b6000613c957f0000000000000000000000000000000000000000000000000000000000000001613d31565b905080600003613cb857604051634c8f99a760e11b815260040160405180910390fd5b613cc281836159a9565b979650505050505050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d0d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126d19190615cc3565b6001600160401b0381166000908152602081905260408120546001600160a01b03168015613e0657806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613db3575060408051601f3d908101601f19168201909252613db091810190615cfa565b60015b15613e065760008413613dd95760405163119d4d6b60e11b815260040160405180910390fd5b81600003613dfa576040516376685d7f60e11b815260040160405180910390fd5b50919695505050505050565b50506001600160401b031660009081526007602052604090205490565b6000613e4e7f55b101fc856aff484166c46ad33bc74831c135693c159b0092bb3b72254ffb6b612645565b6001600160a01b03166313c02a596040518163ffffffff1660e01b8152600401602060405180830381865afa158015613e8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613eaf91906149b7565b9050613eba81615890565b905090565b6001600160401b0381166000908152600160205260408120546001600160a01b03168015613f6757806001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015613f41575060408051601f3d908101601f19168201909252613f3e91810190615cfa565b60015b15613f675760008413613dd95760405163119d4d6b60e11b815260040160405180910390fd5b50506001600160401b031660009081526008602052604090205490565b8060a081901c60c082901c6000819003613fb15760405163030042b760e01b815260040160405180910390fd5b9193909250565b604051806101600160405280600081526020016000815260200160008152602001600081526020016140186040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b81526060602082018190526000604083018190528183018190526080830181905260a083015260c09091015290565b604051806101600160405280606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160006001600160a01b0316815260200160006001600160a01b03168152602001606081525090565b6001600160401b03811681146140c857600080fd5b50565b6000602082840312156140dd57600080fd5b8135610a74816140b3565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715614120576141206140e8565b60405290565b60405161014081016001600160401b0381118282101715614120576141206140e8565b60405161016081016001600160401b0381118282101715614120576141206140e8565b604051601f8201601f191681016001600160401b0381118282101715614194576141946140e8565b604052919050565b60006001600160401b038211156141b5576141b56140e8565b5060051b60200190565b60ff811681146140c857600080fd5b600082601f8301126141df57600080fd5b813560206141f46141ef8361419c565b61416c565b8083825260208201915060208460051b87010193508684111561421657600080fd5b602086015b8481101561423b57803561422e816141bf565b835291830191830161421b565b509695505050505050565b60006001600160401b0382111561425f5761425f6140e8565b50601f01601f191660200190565b600082601f83011261427e57600080fd5b813561428c6141ef82614246565b8181528460208386010111156142a157600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080608085870312156142d457600080fd5b84356001600160401b03808211156142eb57600080fd5b6142f7888389016141ce565b9550602091508187013561430a816140b3565b945060408701358181111561431e57600080fd5b61432a89828a0161426d565b94505060608701358181111561433f57600080fd5b8701601f8101891361435057600080fd5b803561435e6141ef8261419c565b81815260059190911b8201840190848101908b83111561437d57600080fd5b8584015b838110156143b5578035868111156143995760008081fd5b6143a78e898389010161426d565b845250918601918601614381565b50989b979a50959850505050505050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b81811015614409578451835293830193918301916001016143ed565b5090979650505050505050565b60008083601f84011261442857600080fd5b5081356001600160401b0381111561443f57600080fd5b6020830191508360208260051b850101111561445a57600080fd5b9250929050565b6000806000806060858703121561447757600080fd5b8435614482816140b3565b935060208501356001600160401b038082111561449e57600080fd5b6144aa88838901614416565b909550935060408701359150808211156144c357600080fd5b506144d08782880161426d565b91505092959194509250565b60005b838110156144f75781810151838201526020016144df565b50506000910152565b600081518084526145188160208601602086016144dc565b601f01601f19169290920160200192915050565b828152604060208201526000610f206040830184614500565b80151581146140c857600080fd5b803561455e81614545565b919050565b60008060006060848603121561457857600080fd5b833561458381614545565b925060208401356001600160401b0381111561459e57600080fd5b6145aa868287016141ce565b92505060408401356145bb816140b3565b809150509250925092565b602081526000610a746020830184614500565b6000602082840312156145eb57600080fd5b5035919050565b60006060828403121561460457600080fd5b50919050565b6000806040838503121561461d57600080fd5b82356001600160401b0381111561463357600080fd5b61463f858286016145f2565b925050602083013561465081614545565b809150509250929050565b60006020828403121561460457600080fd5b6000806040838503121561468057600080fd5b82356001600160401b0381111561469657600080fd5b61463f8582860161465b565b6000806000606084860312156146b757600080fd5b83356146c2816140b3565b92506020840135915060408401356001600160401b038111156146e457600080fd5b6146f08682870161426d565b9150509250925092565b6000806000806040858703121561471057600080fd5b84356001600160401b038082111561472757600080fd5b61473388838901614416565b9096509450602087013591508082111561474c57600080fd5b818701915087601f83011261476057600080fd5b81358181111561476f57600080fd5b8860206101a08302850101111561478557600080fd5b95989497505060200194505050565b6000808284036101c08112156147a957600080fd5b83356147b4816140b3565b92506101a0601f19820112156147c957600080fd5b506020830190509250929050565b6000602082840312156147e957600080fd5b81356001600160401b038111156147ff57600080fd5b610f208482850161426d565b60008060008060006060868803121561482357600080fd5b853561482e816140b3565b945060208601356001600160401b038082111561484a57600080fd5b61485689838a01614416565b9096509450604088013591508082111561486f57600080fd5b5061487c88828901614416565b969995985093965092949392505050565b600080600080600080606087890312156148a657600080fd5b86356001600160401b03808211156148bd57600080fd5b6148c98a838b01614416565b909850965060208901359150808211156148e257600080fd5b6148ee8a838b01614416565b9096509450604089013591508082111561490757600080fd5b5061491489828a01614416565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03811681146140c857600080fd5b805161455e8161493c565b60006020828403121561496e57600080fd5b8151610a748161493c565b6001600160401b038416815260606020820152600061499b6060830185614500565b82810360408401526149ad8185614500565b9695505050505050565b6000602082840312156149c957600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156126d1576126d16149d0565b60008151808452602080850194506020840160005b83811015614a2a57815187529582019590820190600101614a0e565b509495945050505050565b600060208083528351604082850152614a5160608501826149f9565b82860151601f198683038101604088015281518084529293509084019183850190600581901b8501860160005b82811015614aaa5784878303018452614a98828751614500565b95880195938801939150600101614a7e565b509998505050505050505050565b60208152815160208201526000602083015160606040840152614ade60808401826149f9565b90506040840151601f198483030160608501526132fc82826149f9565b602081528151602082015260006020830151604080840152610f206060840182614500565b600181811c90821680614b3457607f821691505b60208210810361460457634e487b7160e01b600052602260045260246000fd5b600082601f830112614b6557600080fd5b8151614b736141ef82614246565b818152846020838601011115614b8857600080fd5b610f208260208301602087016144dc565b600060208284031215614bab57600080fd5b81516001600160401b03811115614bc157600080fd5b610f2084828501614b54565b600082601f830112614bde57600080fd5b81516020614bee6141ef8361419c565b8083825260208201915060208460051b870101935086841115614c1057600080fd5b602086015b8481101561423b5780518352918301918301614c15565b600060c08284031215614c3e57600080fd5b614c466140fe565b905081516001600160401b03811115614c5e57600080fd5b614c6a84828501614b54565b8252506020820151614c7b8161493c565b60208201526040820151614c8e8161493c565b60408201526060820151614ca1816141bf565b60608201526080820151614cb4816140b3565b8060808301525060a082015160a082015292915050565b600082601f830112614cdc57600080fd5b81516020614cec6141ef8361419c565b82815260059290921b84018101918181019086841115614d0b57600080fd5b8286015b8481101561423b5780516001600160401b03811115614d2e5760008081fd5b614d3c8986838b0101614c2c565b845250918301918301614d0f565b805161455e81614545565b600082601f830112614d6657600080fd5b81516020614d766141ef8361419c565b8083825260208201915060208460051b870101935086841115614d9857600080fd5b602086015b8481101561423b578051614db081614545565b8352918301918301614d9d565b600060208284031215614dcf57600080fd5b81516001600160401b0380821115614de657600080fd5b908301906101408286031215614dfb57600080fd5b614e03614126565b82518152602083015182811115614e1957600080fd5b614e2587828601614bcd565b602083015250604083015182811115614e3d57600080fd5b614e4987828601614bcd565b604083015250606083015182811115614e6157600080fd5b614e6d87828601614bcd565b606083015250608083015182811115614e8557600080fd5b614e9187828601614bcd565b60808301525060a083015182811115614ea957600080fd5b614eb587828601614ccb565b60a08301525060c083015182811115614ecd57600080fd5b614ed987828601614d55565b60c08301525060e083015182811115614ef157600080fd5b614efd87828601614d55565b60e083015250610100614f11818501614951565b908201526101208381015183811115614f2957600080fd5b614f3588828701614b54565b918301919091525095945050505050565b600060208284031215614f5857600080fd5b81516001600160401b0380821115614f6f57600080fd5b908301906101408286031215614f8457600080fd5b614f8c614126565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015182811115614fca57600080fd5b614fd687828601614c2c565b60a083015250614fe860c08401614d4a565b60c0820152614ff960e08401614d4a565b60e0820152610100614f11818501614951565b6000602080838503121561501f57600080fd5b82516001600160401b0381111561503557600080fd5b8301601f8101851361504657600080fd5b80516150546141ef8261419c565b81815260059190911b8201830190838101908783111561507357600080fd5b928401925b82841015613cc257835161508b816141bf565b82529284019290840190615078565b6000823561015e198336030181126150b157600080fd5b9190910192915050565b803561455e8161493c565b600060c082840312156150d857600080fd5b6150e06140fe565b905081356001600160401b038111156150f857600080fd5b6151048482850161426d565b82525060208201356151158161493c565b602082015260408201356151288161493c565b6040820152606082013561513b816141bf565b6060820152608082013561514e816140b3565b8060808301525060a082013560a082015292915050565b6000610160828403121561517857600080fd5b615180614149565b90508135815260208201356020820152604082013560408201526060820135606082015260808201356001600160401b03808211156151be57600080fd5b6151ca858386016150c6565b608084015260a08401359150808211156151e357600080fd5b6151ef8583860161426d565b60a084015261520060c08501614553565b60c084015261521160e08501614553565b60e084015261010091506152268285016150bb565b82840152610120915061523a8285016150bb565b828401526101409150818401358181111561525457600080fd5b6152608682870161426d565b8385015250505092915050565b60006126d13683615165565b6000808335601e1984360301811261529057600080fd5b8301803591506001600160401b038211156152aa57600080fd5b6020019150600581901b360382131561445a57600080fd5b600082601f8301126152d357600080fd5b813560206152e36141ef8361419c565b8083825260208201915060208460051b87010193508684111561530557600080fd5b602086015b8481101561423b578035835291830191830161530a565b600082601f83011261533257600080fd5b813560206153426141ef8361419c565b82815260059290921b8401810191818101908684111561536157600080fd5b8286015b8481101561423b5780356001600160401b038111156153845760008081fd5b6153928986838b01016150c6565b845250918301918301615365565b600082601f8301126153b157600080fd5b813560206153c16141ef8361419c565b8083825260208201915060208460051b8701019350868411156153e357600080fd5b602086015b8481101561423b5780356153fb81614545565b83529183019183016153e8565b6000610160828403121561541b57600080fd5b615423614149565b905081356001600160401b038082111561543c57600080fd5b615448858386016152c2565b8352602084013591508082111561545e57600080fd5b61546a858386016152c2565b6020840152604084013591508082111561548357600080fd5b61548f858386016152c2565b604084015260608401359150808211156154a857600080fd5b6154b4858386016152c2565b606084015260808401359150808211156154cd57600080fd5b6154d985838601615321565b608084015260a08401359150808211156154f257600080fd5b6154fe8583860161426d565b60a084015260c084013591508082111561551757600080fd5b615523858386016153a0565b60c084015260e084013591508082111561553c57600080fd5b615211858386016153a0565b60006126d13683615408565b60006020828403121561556657600080fd5b8151610a7481614545565b601f821115611362576000816000526020600020601f850160051c8101602086101561559a5750805b601f850160051c820191505b818110156114a3578281556001016155a6565b81516001600160401b038111156155d2576155d26140e8565b6155e6816155e08454614b20565b84615571565b602080601f83116001811461561b57600084156156035750858301515b600019600386901b1c1916600185901b1785556114a3565b600085815260208120601f198616915b8281101561564a5788860151825594840194600190910190840161562b565b50858210156156685787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006156866141ef8461419c565b80848252602080830192508560051b8501368111156156a457600080fd5b855b81811015613dfa5780356001600160401b038111156156c55760008081fd5b6156d136828a01615165565b8652509382019382016156a6565b60006156ed6141ef8461419c565b80848252602080830192508560051b85013681111561570b57600080fd5b855b81811015613dfa5780356001600160401b0381111561572c5760008081fd5b61573836828a01615408565b86525093820193820161570d565b60006020828403121561575857600080fd5b81516001600160401b038082111561576f57600080fd5b908301906040828603121561578357600080fd5b60405160408101818110838211171561579e5761579e6140e8565b604052825181526020830151828111156157b757600080fd5b6157c387828601614b54565b60208301525095945050505050565b6040808252810183905260008460608301825b8681101561580f5782356157f8816141bf565b60ff168252602092830192909101906001016157e5565b508381036020850152613cc28186614500565b60006020828403121561583457600080fd5b8135610a74816141bf565b604080825283519082018190526000906020906060840190828701845b8281101561587b57815160ff168452928401929084019060010161585c565b5050508381036020850152613b0a8186614500565b6000600182016158a2576158a26149d0565b5060010190565b6000602082840312156158bb57600080fd5b8135610a748161493c565b6001600160401b03831681526101c081016158f4602083016158e7856150bb565b6001600160a01b03169052565b615900602084016150bb565b6001600160a01b0381166040840152506040830135606083015260608301356080830152608083013560a083015260a083013560c083015260c083013560e083015261010060e0840135818401526101208185013581850152610140915080850135828501525061016081850135818501526101809150808501358285015250808401356101a0840152509392505050565b80820281158282048414176126d1576126d16149d0565b6000826159c657634e487b7160e01b600052601260045260246000fd5b500490565b6000808335601e198436030181126159e257600080fd5b8301803591506001600160401b038211156159fc57600080fd5b60200191503681900382131561445a57600080fd5b6000815160c08452615a2660c0850182614500565b9050602083015160018060a01b038082166020870152806040860151166040870152505060ff60608401511660608501526001600160401b03608084015116608085015260a083015160a08501528091505092915050565b6020815281516020820152602082015160408201526040820151606082015260608201516080820152608082015160a0820152600060a08301516101408060c0850152615acf610160850183615a11565b915060c0850151615ae460e086018215159052565b5060e0850151610100615afa8187018315159052565b8601519050610120615b16868201836001600160a01b03169052565b860151858403601f19018387015290506149ad8382614500565b60008282518085526020808601955060208260051b8401016020860160005b8481101561440957601f19868403018952615b6b838351615a11565b98840198925090830190600101615b4f565b60008151808452602080850194506020840160005b83811015614a2a578151151587529582019590820190600101615b92565b602081528151602082015260006020830151610140806040850152615bd96101608501836149f9565b91506040850151601f1980868503016060870152615bf784836149f9565b93506060870151915080868503016080870152615c1484836149f9565b935060808701519150808685030160a0870152615c3184836149f9565b935060a08701519150808685030160c0870152615c4e8483615b30565b935060c08701519150808685030160e0870152615c6b8483615b7d565b935060e08701519150610100818786030181880152615c8a8584615b7d565b945080880151925050610120615caa818801846001600160a01b03169052565b8701518685039091018387015290506149ad8382614500565b600060208284031215615cd557600080fd5b8151610a74816141bf565b805169ffffffffffffffffffff8116811461455e57600080fd5b600080600080600060a08688031215615d1257600080fd5b615d1b86615ce0565b9450602086015193506040860151925060608601519150615d3e60808701615ce0565b9050929550929590935056fe6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa8684a76dea3a6231aa5446f85ecde36fb499385f0f3539e800a138fb9855200db67bcc180fb907e9ae431665de4bc74305c00b7b27442aadd477980ecc4bb14c011a2646970667358221220f9bde5d8b97499d4bda470d0f2b1126f4ac099c2b82dbf857109419d6cad275664736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
-----Decoded View---------------
Arg [0] : superRegistry_ (address): 0x17A332dC7B40aE701485023b219E9D6f493a2514
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.