Overview
WEMIX Balance
WEMIX Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
CrossBridgeOrigin
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "contracts/interfaces/IEXBridge.sol"; import { CrossBridgeBase } from "contracts/cross-bridge/CrossBridgeBase.sol"; import { Sig } from "contracts/interfaces/UniversalTypes.sol"; import { SlotAdminable } from "contracts/access/SlotAdminable.sol"; import { INCPStaking } from "contracts/wemix/wonder/interfaces/INCPStaking.sol"; import "contracts/wemix/wonder/interfaces/IWithdrawalNFT.sol"; contract CrossBridgeOrigin is ICrossBridgeOrigin, CrossBridgeBase { constructor( address owner, StakingInfo memory _stakingInfo ) { initCrossBridgeOrigin( owner, _stakingInfo ); } function initCrossBridgeOrigin( address owner, StakingInfo memory _stakingInfo ) public override initializer { _transferOwnership(msg.sender); setStakingInfo(_stakingInfo); _transferOwnership(owner); } receive() whenNotPaused external payable override { } function toRemote(address account) whenNotPaused public payable override { if(account == address(0)) account = msg.sender; ConfigSnapshot memory snapshot = _getBridgeSnapshot(); _processBridgeTransfer(snapshot, BridgeMessage(account, msg.value), true); _claimReward(stakingInfo); } function requestReceive( uint64 srcNonce, BridgeMessage memory msgBridge, Sig[] memory sigs ) whenNotPaused external override returns(uint256[] memory withdrawalIds) { require(!filterSrcNonce[srcNonce], "src nonce"); filterSrcNonce[srcNonce] = true; ConfigSnapshot memory snapshot = _getBridgeSnapshot(); snapshot.localAsset = _processBridgeReceive(snapshot, srcNonce, msgBridge, sigs); withdrawalIds = _requestUnstake(msgBridge); _updateAssetInfo(snapshot.localAsset); _claimReward(stakingInfo); } function completeReceive(uint256 ncpId, uint256 withdrawalId) whenNotPaused external override { _completeUnstake(ncpId, withdrawalId); } function claimReward() whenNotPaused public override { _claimReward(stakingInfo); } function sync() whenNotPaused external payable override { ConfigSnapshot memory snapshot = _getBridgeSnapshot(); address _syncAccount = syncAccount; require(msg.sender == _syncAccount, "sync"); _stake(msg.value); snapshot.localAsset.bridgeTotalLocked += uint128(msg.value); snapshot.localAsset.bridgeTotalSyncStaking += uint128(msg.value); _updateAssetInfo(snapshot.localAsset); uint64 _localNonce = _useLocalNonce(); emit Sync(_localNonce, _syncAccount, msg.value); } function requestWithdrawFee(uint256 amount) public override onlyAuthorized returns (uint256[] memory withdrawalIds) { address _feeAccount = feeAccount; StakingInfo memory _stakingInfo = stakingInfo; INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); (uint8[] memory ncpIds, uint128[] memory tmp) = _determineUnstakePid(_stakingInfo, uint128(amount)); uint256 tmpAmount; for(uint256 i; i<ncpIds.length; i++) { tmpAmount = tmp[i]; tmp[i] = uint128(staking.withdrawRequest( ncpIds[i], // ncpId default ncpIds[i], // toPid default tmpAmount, // amount payable(address(this)), // to false, // claimReward false // comp )); require(filterWithdrawalId[tmp[i]] == address(0), "withdrawalId"); filterWithdrawalId[tmp[i]] = address(this); emit RequestFeeWithdrawal(_feeAccount, ncpIds[i], tmp[i], tmpAmount); } assembly { withdrawalIds := tmp } } function completeWithrawFee(uint256 ncpId, uint256 withdrawalId) public override { require(filterWithdrawalId[withdrawalId] == address(this), "withdrawalId filter"); delete filterWithdrawalId[withdrawalId]; address _feeAccount = feeAccount; INCPStaking staking = INCPStaking(stakingInfo.stake_contract); uint256 amount = staking.withdrawalNFT().getWithdrawalRequestInfo(withdrawalId).amount; uint256 beforeBalance = address(this).balance; staking.withdraw( ncpId, withdrawalId, payable( address(this) ) ); require(address(this).balance - beforeBalance == amount, "withdraw amount"); emit CompleteFeeWithdrawal(_feeAccount, ncpId, withdrawalId); _trySendValueCatchFail(payable(_feeAccount), amount); } function _processBridgeTransfer( ConfigSnapshot memory snapshot, BridgeMessage memory msgBridge, bool applyingFee ) internal { uint256 feeAmount; _checkBridgeTransferAmount(msgBridge.amount, snapshot.bridgeAmountConfig); if (applyingFee) { feeAmount = _calcFee(msgBridge.amount, snapshot.feeConfig); require(msgBridge.amount > feeAmount, "fee amount"); unchecked{ msgBridge.amount -= feeAmount; } _trySendValueCatchFail(payable(feeAccount), feeAmount); } snapshot.localAsset.bridgeTotalLocked += uint128(msgBridge.amount); _updateAssetInfo(snapshot.localAsset); uint64 _localNonce = _useLocalNonce(); emit ToRemote(_localNonce, msgBridge.account, msgBridge.amount, feeAmount); _stake(msgBridge.amount); } function _stake(uint256 amount) internal { StakingInfo memory _stakingInfo = stakingInfo; INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); (uint8[] memory ncpIds, uint128[] memory tmp) = _determineStakePid(_stakingInfo, uint128(amount)); for(uint256 i; i<ncpIds.length; i++) { staking.deposit{value: tmp[i]}( ncpIds[i], //ncpId default tmp[i], //amount payable(address(this)), //payable to false, //claimReward false //comp ); } } function _processBridgeReceive( ConfigSnapshot memory snapshot, uint64 srcNonce, BridgeMessage memory msgBridge, Sig[] memory sigs ) internal returns(AssetInfo memory) { _verifyToOriginMessage(srcNonce, msgBridge, sigs); snapshot.localAsset.bridgeTotalLocked -= uint128(msgBridge.amount); emit ToOriginReceived(srcNonce, msgBridge.account, msgBridge.amount); return snapshot.localAsset; } function _requestUnstake(BridgeMessage memory msgBridge) internal returns (uint256[] memory withdrawalIds) { StakingInfo memory _stakingInfo = stakingInfo; INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); (uint8[] memory ncpIds, uint128[] memory tmp) = _determineUnstakePid(_stakingInfo, uint128(msgBridge.amount)); uint256 tmpAmount; for(uint256 i; i<ncpIds.length; i++) { tmpAmount = tmp[i]; tmp[i] = uint128(staking.withdrawRequest( ncpIds[i], // ncpId default ncpIds[i], // toPid default tmpAmount, // amount payable(address(this)), // to false, // claimReward false // comp )); require(filterWithdrawalId[tmp[i]] == address(0), "withdrawalId"); filterWithdrawalId[tmp[i]] = msgBridge.account; emit ReceivePending(msgBridge.account, ncpIds[i], tmp[i], tmpAmount); } // optimize: array type change assembly { withdrawalIds := tmp } } function _completeUnstake(uint256 ncpId, uint256 withdrawalId) internal { address account = filterWithdrawalId[withdrawalId]; require(account != address(0), "withdrawalId filter"); delete filterWithdrawalId[withdrawalId]; INCPStaking staking = INCPStaking(stakingInfo.stake_contract); uint256 amount = staking.withdrawalNFT().getWithdrawalRequestInfo(withdrawalId).amount; uint256 beforeBalance = address(this).balance; staking.withdraw( ncpId, withdrawalId, payable( address(this) ) ); require(address(this).balance - beforeBalance == amount, "withdraw amount"); _trySendValueCatchFail(payable(account), amount); emit ReceiveComplete(account, ncpId, withdrawalId); } function _determineStakePid( StakingInfo memory _stakingInfo, uint128 amount ) internal pure returns ( uint8[] memory ncpIds, uint128[] memory amounts ) { require(_stakingInfo.ncpIds.length == 1, "default ncpId"); ncpIds = _stakingInfo.ncpIds; amounts = new uint128[](1); amounts[0] = amount; } function _determineUnstakePid( StakingInfo memory _stakingInfo, uint128 amount ) internal pure returns ( uint8[] memory ncpIds, uint128[] memory amounts ) { return _determineStakePid(_stakingInfo, amount); } function _claimReward(StakingInfo memory _stakingInfo) internal returns (uint256 reward_amount) { address _syncAccount = syncAccount; require(_syncAccount != address(0), "sync zero"); INCPStaking staking = INCPStaking(_stakingInfo.stake_contract); reward_amount = _syncAccount.balance; for(uint256 i; i<_stakingInfo.ncpIds.length; i++) { staking.claim(_stakingInfo.ncpIds[i], _syncAccount); } reward_amount = _syncAccount.balance - reward_amount; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { Sig } from "contracts/interfaces/UniversalTypes.sol"; import { INCPStaking } from "contracts/wemix/wonder/interfaces/INCPStaking.sol"; import { IEcoERC20 } from "contracts/interfaces/IEcoERC20.sol"; struct ConfigSnapshot { FeeConfig feeConfig; BridgeAmountConfig bridgeAmountConfig; AssetInfo localAsset; } struct StakingInfo { address stake_contract; uint8[] ncpIds; } struct FeeConfig { uint256 min; uint256 max; uint32 rate; } struct BridgeAmountConfig { uint256 min; uint256 max; uint128 toOriginNativeFee; uint128 toRemoteNativeSwapAmount; } struct AssetInfo { uint128 bridgeTotalLocked; uint128 bridgeTotalSyncStaking; } struct BridgeContractInfo { uint32 chainId; address bridge; uint64 nonce; } struct BridgeMessage { address account; uint256 amount; } enum BrigeMessegeType { NoneType, ToRemote, ToOrigin, Sync } struct RemoteFeeOracle { address oracleAddress; } interface IEXBridgeBase { event FailSendValue(address indexed to, uint256 amount); function rateBase() external pure returns (uint32); function getSrcBridgeContractInfo() external view returns (BridgeContractInfo memory); function getStakingInfo() external view returns (StakingInfo memory); function getFeeConfig() external view returns (FeeConfig memory); function getBridgeAmountConfig() external view returns (BridgeAmountConfig memory); function getLocalAsset() external view returns (AssetInfo memory); function localNonce() external view returns (uint64); function filterSrcNonce(uint256 sourceNonce) external view returns (bool filtered); function filterWithdrawalId(uint256 withdrawalId) external view returns (address account); function remoteOracle() external view returns(address); function setFeeAccount(address _feeAccount) external; function setSyncAccount(address _syncAccount) external; function setBridgePairInfo(BridgeContractInfo memory _pairBridgeInfo) external; function setFeeConfig(FeeConfig memory _feeConfig) external; function setStakingInfo(StakingInfo memory _stakingInfo) external; function setBridgeAmountConfig(BridgeAmountConfig memory _bridgeAmountConfig) external; function setRemoteOracle(address _remoteOracle) external; function calcBridgeTransferAmount(uint256 amount) external view returns (uint256 transferAmount, uint256 feeAmount); function calcFee(uint256 amount) external view returns (uint256 feeAmount); function recoversToOriginMessage( uint64 nonce, BridgeMessage memory msgToOrigin, Sig[] memory sigs ) external view returns (address[] memory signers); function recoversToRemoteMessage( uint64 nonce, BridgeMessage memory msgToRemote, Sig[] memory sigs ) external view returns (address[] memory signers); function recoversSyncMessage( uint64 nonce, uint256 amount, Sig[] memory sigs ) external view returns (address[] memory signers); } interface ICrossBridgeOrigin is IEXBridgeBase { event ToRemote(uint64 indexed localNonce, address indexed account, uint256 amount, uint256 feeAmount); event ToOriginReceived(uint64 indexed srcNonce, address indexed account, uint256 amount); event Sync(uint64 indexed localNonce, address indexed account, uint256 amount); event ReceivePending(address indexed account, uint256 indexed ncpId, uint256 nftId, uint256 amount); event ReceiveComplete(address indexed account, uint256 indexed ncpId, uint256 indexed nftId); event RequestFeeWithdrawal(address indexed account, uint256 indexed ncpId, uint256 nftId, uint256 amount); event CompleteFeeWithdrawal(address indexed account, uint256 indexed ncpId, uint256 indexed nftId); receive() external payable; function initCrossBridgeOrigin(address owner, StakingInfo memory _stakingInfo) external; function toRemote(address account) external payable; function requestReceive( uint64 srcNonce, BridgeMessage memory msgBridge, Sig[] memory sigs ) external returns (uint256[] memory withdrawalIds); function completeReceive(uint256 ncpId, uint256 withdrawalId) external; function claimReward() external; function sync() external payable; function requestWithdrawFee(uint256 amount) external returns (uint256[] memory withdrawalIds); function completeWithrawFee(uint256 ncpId, uint256 withdrawalId) external ; } interface ICrossBridgeRemote is IEXBridgeBase { event ToOrigin(uint64 indexed localNonce, address indexed account, uint256 amount, uint256 feeAmount); event ToRemoteReceived(uint64 indexed srcNonce, address indexed account, uint256 amount); event SyncReceived(uint64 indexed localNonce, address indexed account, uint256 amount); event Deposit(address indexed account, uint256 amount); event Withdrawal(address indexed account, uint256 amount); receive() external payable; function initCrossBridgeRemote(address owner, IEcoERC20 _token) external; function setRemoteToken(IEcoERC20 _remoteToken) external; function getRemoteToken() external view returns (IEcoERC20); function deposit() external payable; function withdraw(uint256 amount) external; function toOrigin(address to, uint256 amount) external payable; function completeReceive(uint64 srcNonce, BridgeMessage memory msgBridge, Sig[] memory sigs) external; function completeSync(uint64 srcNonce, uint256 amount, Sig[] memory sigs) external; } interface IEXOriginStakingBase { function wonderStaking() external view returns (INCPStaking); function syncAccount() external view returns (address payable); function initEXOriginStaking(address owner, INCPStaking _wonderStaking, address payable _syncAccount) external; receive() external payable; function setWonderStaking(INCPStaking _wonderStaking) external; function setSyncAccount(address payable _syncAccount) external; } interface IEXOriginStaking is IEXOriginStakingBase { function stake(uint256 ncpId) external payable; function claimReward(uint256 ncpId) external; function unstakeRequest(uint256 ncpId, uint256 amount, address payable account) external returns (uint256 tokenId); function unstake(uint256 ncpId, uint256 tokenId, address payable account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; struct Sig { uint8 v; bytes32 r; bytes32 s; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "contracts/token/ERC20/IERC20.sol"; import "contracts/wemix/wonder/interfaces/IRewarder.sol"; import "contracts/wemix/wonder/interfaces/IWithdrawalNFT.sol"; /// @author @seunghwalee interface INCPStaking { /* =========== STATE VARIABLES ===========*/ function withdrawalNFT() external returns(IWithdrawalNFT); /** * @notice Info of each WEMIX 3.0 Staking user. * `amount` LP token amount the user has provided. * `rewardDebt` The amount of reward entitled to the user. * `pendingReward` The amount of rewards(lp + mp) the user will receive. * `pendingAmountReward` The amount of rewards(lp) the user will receive. * `withdrawRequest` The withdrawal request info from user. */ struct UserInfo { uint256 amount; uint256 rewardDebt; uint256 pendingReward; uint256 pendingAmountReward; uint256 lastRewardClaimed; } /** * @notice Info of each WEMIX 3.0 Staking user. * `staked` Current user's mp amount. * `lastMPUpdatedTime` The amount of reward entitled to the user. */ struct UserMPInfo { uint256 staked; uint256 lastMPUpdatedTime; } /** * @notice Info of each WEMIX 3.0 Staking user. * `staked` Current user's mp amount. * `lastMPUpdatedTime` The amount of reward entitled to the user. */ struct FeeRatioRequestInfo { uint256 ratio; uint256 requestBlockNumber; } /** * @notice Info of each WEMIX 3.0 Staking pool. * `accRewardPerShare` Accumulated reward per share. * `accMPPerShare` Accumulated mp per share. * `lastRewardBlock` Last block number that Rewards distribution occurs. * `totalDeposit` The amount of total deposit lp token. * `totalMP` The amount of total deposit mp. * `rewardToken` The address of the reward token. * `isInputNative` True if lp token is native coin. * `isRewardNative` True if reward token is native coin. * `activatedMP` True if mp is used. * `lock` True in case of emergency. * `path` The Path to be used when running compound function. * `breaker` The address of breaker. * `breakerSetter` The address of breakerSetter. * `feeRatio` The withdrawal fee ratio. */ struct PoolInfo { address ncp; bytes name; uint256 accRewardPerShare; uint256 accMPPerShare; uint256 lastRewardBlock; uint256 totalDeposit; uint256 totalMP; uint256 unbondTime; uint256 totalRequestedWithdrawal; uint256 feeRatio; bool activatedMP; bool lock; address breaker; address breakerSetter; address feeCollector; uint256 totalDepositors; } function version() external view returns (uint256); /** * @notice Add a new LP to the pool. Can only be called by the owner. * DO NOT add the same LP token more than once. Rewards will be messed up if you do. * @param _ncp Address of ncp. * @param _feeCollector Address of the fee collector. * @param _rewarder Address of the rewarder delegate. * @param _activatedMP True if mp is used. * @param _lock True in case of emergency. * @param _breaker The address of breaker. * @param _breakerSetter The address of breakerSetter. * @param _feeRatio The withdrawal fee ratio. */ function add( address _ncp, address _feeCollector, IRewarder _rewarder, bool _activatedMP, bool _lock, address _breaker, address _breakerSetter, uint256 _feeRatio, uint256 _initValue ) external; /* =========== SET FUNCTIONS =========== */ /** * @notice Changed fee collector. only rewarder owner can change it's fee collector. * @param pid The index of the pool. See `poolInfo`. * @param _feeCollector Address of the fee collector. */ function setFeeCollector( uint256 pid, address _feeCollector ) external; function setPoolBreaker(uint256 pid, address _breaker) external; function setPoolBreakerSetter(uint256 pid, address _breakerSetter) external; function lockContract(uint256 pid) external; function unlockContract(uint256 pid) external; /** * @notice View function to see pending reward token on frontend. * @param pid The index of the pool. See `poolInfo`. * @param _user Address of user. * @return pending reward for a given user. */ function pendingReward( uint256 pid, address _user ) external view returns (uint256 pending); /** * @notice View function to see pending reward token on frontend. * @param pid The index of the pool. See `poolInfo`. * @param _user Address of user. * @return totalPendingReward total reward for a given user. * @return lpPendingReward lp reward for a given user. * @return mpPendingReward mp reward for a given user. */ function pendingRewardInfo( uint256 pid, address _user ) external view returns ( uint256 totalPendingReward, uint256 lpPendingReward, uint256 mpPendingReward ); /** * @notice View function to see pending reward token on frontend. * @param pid The index of the pool. See `poolInfo`. * @param account Address of user. * @return mpAmount The amount of mp to receive when updateMP function is executed. */ function pendingMP( uint256 pid, address account ) external view returns (uint256 mpAmount); /** * @notice The number of WEMIX 3.0 Staking pools. * @return pools Pool lengths. */ function poolLength() external view returns (uint256 pools); /** * @notice View function to see user staking info. * @param pid The index of the pool. See `poolInfo`. * @param account Address of user. * @return info user staking info */ function getUserInfo( uint256 pid, address account ) external view returns (UserInfo memory info); /** * @notice View function to see user multiplier info. * @param pid The index of the pool. See `poolInfo`. * @param account Address of user. * @return info user multiplier point info */ function getUserMPInfo( uint256 pid, address account ) external view returns (UserMPInfo memory info); /** * @notice View function to see staking pool info. * @param pid The index of the pool. See `poolInfo`. * @return info staking pool info */ function getPoolInfo( uint256 pid ) external view returns (PoolInfo memory info); /** * @notice View function to see staking token address. * @param pid The index of the pool. See `poolInfo`. * @return addr staking pool rewarder address */ function getRewarder(uint256 pid) external view returns (address addr); /** * @notice Update reward variables for all pools. Be careful of gas spending! * @param pids Pool IDs of all to be updated. Make sure to update all active pools. */ function massUpdatePools(uint256[] calldata pids) external; /** * @notice Update reward variables of the given pool. * @param pid The index of the pool. See `poolInfo`. * @return pool Returns the pool that was updated. */ function updatePool( uint256 pid ) external payable returns (PoolInfo memory pool); /** * @notice Deposit LP tokens to WEMIX 3.0 Staking for reward. * @param pid The index of the pool. See `poolInfo`. * @param amount LP token amount to deposit. * @param to The receiver of `amount` deposit benefit. */ function deposit( uint256 pid, uint256 amount, address payable to, bool claimReward, bool comp ) external payable; /** * @notice Withdraw LP tokens from WEMIX 3.0 Staking. * @param pid The index of the pool. See `poolInfo`. * @param tokenId withdrawal tokenid. * @param to Receiver of the LP tokens. */ function withdraw( uint256 pid, uint256 tokenId, address payable to ) external; /** * @notice Withdraw LP tokens from WEMIX 3.0 Staking. * @param pid The index of the pool. See `poolInfo`. * @param toPid The index of the pool whose staking will change. * @param amount LP token amount to withdraw. * @param to Receiver of the LP tokens. */ function withdrawRequest( uint256 pid, uint256 toPid, uint256 amount, address payable to, bool claimReward, bool comp ) external returns (uint256); /** * @notice Harvest proceeds for transaction sender to `to`. * @param pid The index of the pool. See `poolInfo`. * @param to Receiver of rewards. */ function claim(uint256 pid, address to) external; /** * @notice Compound proceeds for transaction sender to `to`. * @param pid The index of the pool. See `poolInfo`. * @param to Receiver of rewards. */ function compound(uint256 pid, address to) external; function computePendingAmountReward( uint256 pendingReward, uint256 lpAmount, uint256 mpAmount ) external pure returns (uint256); function ncpDeposit( uint256 amount, address payable to ) external payable; function ncpWithdraw( uint256 amount, address payable to ) external payable; function getPlatformFeeRatio() external view returns (uint256); /** * @notice View function to see staking pool info. * @param pid The index of the pool. See _poolInfo. * @return info staking pool info */ function getFeeRequestInfo( uint256 pid ) external view returns (FeeRatioRequestInfo memory info); // function massMigration(uint256[] calldata pids, address to) external; // function migration(uint256 pid, address to) external; /* ========== EVENTS ========== */ event Deposit( address indexed user, uint256 indexed pid, uint256 amount, address indexed to, uint256 rewardAmount ); event NCPDeposit( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to, uint256 rewardAmount ); event WithdrawRequest( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to, uint256 rewardAmount ); event Withdraw( address indexed user, uint256 indexed pid, uint256 amount, address indexed to ); event NCPWithdraw( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to ); event Harvest(address indexed user, uint256 indexed pid, uint256 amount); event NCPHarvest( address indexed user, uint256 indexed pid, bytes name, address indexed ncp, uint256 amount, address to ); event LogPoolAddition( uint256 indexed pid, IRewarder indexed rewarder, bool lock, address breaker, address breakerSetter, uint256 feeRatio ); event LogSetPool( uint256 indexed pid, IRewarder indexed rewarder, address feeCollector, uint256 feeRatio ); event LogOnReward(address indexed to, uint256 amount); event SetPoolBreaker(uint256 pid, address breaker); event SetPoolBreakerSetter(uint256 pid, address breakerSetter); event LockContract(uint256 pid); event UnlockContract(uint256 pid); event LogUpdatePool( uint256 indexed pid, uint256 lastRewardBlock, uint256 lpSupply, uint256 accRewardPerShare ); event SetMultiplierPointBasis(uint256 prev, uint256 curr); event SetUnbondTime(uint256 time); event SetFeeCollector(address prev, address curr); event SetRewardFeeRatioRequest( uint256 pid, uint256 prev, uint256 curr, uint256 executeBlockNumber ); event SetRewardFeeRatio(uint256 pid, uint256 prev, uint256 curr); event SetPlatformFeeRatio(uint256 prev, uint256 curr); event SetWithdrawalNFT(address prev, address curr); event SetRewardFeeRatioRequestDelay(uint256 prev, uint256 curr); ///TODO updateMP event // result updated mp value and pendingReward }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IRewarder { function onReward( address payable to, uint256 amount, address payable feeCollector, uint256 fee, address payable platform, uint256 platformFee ) external returns(uint256); function update() external returns(uint256); function getLastReward() external view returns(uint256); function checkRewarder(address _rewarder) external view returns (uint256); function checkOwner(address _owner) external view returns (bool); event LogOnReward(address to, uint256 amount, address feeCollector, uint256 fee, address platform, uint256 platformFee); event SetRewarder(address rewarder, bool isRewarder); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "contracts/token/ERC721/ERC721Upgradeable.sol"; interface IWithdrawalNFT is IERC721Upgradeable { /** * @notice Info of users withdraw info. * `amount` The amount of withdrawal request. * `requestTime` The time the withdrawal request came in. * `claimableTime` The time of claimable withdrawal. */ struct WithdrawalRequestInfo { uint256 tokenid; uint256 pid; uint256 toPid; uint256 amount; uint256 requestTime; uint256 claimableTime; address drawer; } function mint( address to, uint256 pid, uint256 toPid, uint256 amount, uint256 unbondTime ) external returns (uint256); function burn(address from, uint256 tokenId) external; function getUserTokenList( address user ) external view returns (uint256[] memory); function getWithdrawalRequestInfo( uint256 tokenId ) external view returns (WithdrawalRequestInfo memory); function getWithdrawableTokenList( address user ) external view returns (uint256[] memory); function getFirstWithdrawableToken(uint256 pid, address user) external view returns(uint256); function getWithdrawableTokenListWithPid(uint256 pid, address user) external view returns(uint256[] memory); event Mint(uint256 tokenId, uint256 pid, uint256 toPid, uint256 amount, uint256 mintTime, uint256 unbondTime, address drawer); event Burn(address from, uint256 tokenId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "contracts/token/ERC721/IERC721Upgradeable.sol"; import "contracts/token/ERC721/IERC721ReceiverUpgradeable.sol"; import "contracts/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; import "contracts/utils/AddressUpgradeable.sol"; import "contracts/utils/ContextUpgradeable.sol"; import "contracts/utils/StringsUpgradeable.sol"; import "contracts/utils/introspection/ERC165Upgradeable.sol"; import {Initializable} from "contracts/proxy/utils/Initializable.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { using AddressUpgradeable for address; using StringsUpgradeable for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC721Upgradeable).interfaceId || interfaceId == type(IERC721MetadataUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721Upgradeable.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721Upgradeable.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721Upgradeable.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721Upgradeable.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721ReceiverUpgradeable.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[44] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "contracts/utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "contracts/token/ERC721/IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "contracts/proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "contracts/utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "contracts/utils/math/MathUpgradeable.sol"; import "contracts/utils/math/SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "contracts/utils/introspection/IERC165Upgradeable.sol"; import {Initializable} from "contracts/proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import { IERC20 } from "contracts/token/ERC20/IERC20.sol"; import { IERC20Metadata } from "contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { IAdminable } from "contracts/interfaces/ISlotAdminable.sol"; interface IWETH is IERC20, IERC20Metadata { function deposit() external payable; function withdraw(uint) external; } interface IERC20Burnable is IERC20, IERC20Metadata { function burn(uint256 amount) external; function burnFrom(address account, uint256 amount) external; } interface IERC20Mintable is IAdminable, IERC20, IERC20Metadata { function initERC20Mintable(address owner) external; function mint(address to, uint256 amount) external; } interface IERC20MetadataInitializable is IAdminable, IERC20, IERC20Metadata { function initERC20MetadataInitializable(string memory name_, string memory symbol_, uint8 decimals_) external; } interface IEcoERC20 is IERC20Mintable, IERC20Burnable, IERC20MetadataInitializable {} interface IEcoERC20Pausable is IEcoERC20 {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "contracts/token/ERC20/IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAdminable } from "contracts/access/SlotAdminable.sol";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { Initializable } from "contracts/proxy/utils/Initializable.sol"; import { Ownable } from "contracts/access/Ownable.sol"; import { StorageSlot } from "contracts/utils/StorageSlot.sol"; import { Multicall } from "contracts/utils/Multicall.sol"; import { SlotPausable } from "contracts/access/SlotPausable.sol"; interface IAdminable { event AdminshipTransferred(address indexed previousAdmin, address indexed newAdmin); error Adminship(); function call( address to, uint256 value, bytes calldata data ) external payable returns (bool success, bytes memory returnData); function is_admin(address admin) external returns (bool); function grant_admin(address admin) external; function revoke_admin(address admin) external; function renounceAdminship() external; function pause() external ; function unpause() external ; } contract SlotAdminable is IAdminable, Initializable, Ownable, SlotPausable, Multicall { // This is the keccak-256 hash of "adminable.address.mapping.slot" subtracted by 1 bytes32 private constant _ADMIN_MAP_SLOT = 0xd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b; modifier onlyAuthorized() { if (!(is_admin(_msgSender()) || _msgSender() == owner())) revert Adminship(); _; } // Ownable Override, remove admin ship function _transferOwnership(address newOwner) internal virtual override { address oldOwner = owner(); if (is_admin(oldOwner)) _transferAdminship(oldOwner, address(0)); super._transferOwnership(newOwner); } function call( address to, uint256 value, bytes calldata data ) external payable override onlyOwner returns (bool success, bytes memory returnData) { return to.call{ value: value }(data); } function is_admin(address admin) public view returns (bool) { return get_admin_slot(admin).value; } function grant_admin(address admin) public onlyOwner { _transferAdminship(address(0), admin); } function revoke_admin(address admin) public onlyOwner { _transferAdminship(admin, address(0)); } function renounceAdminship() public { _transferAdminship(_msgSender(), address(0)); } function pause() external onlyAuthorized { _pause(); } function unpause() external onlyAuthorized { _unpause(); } function get_admin_slot(address admin) internal pure returns (StorageSlot.BooleanSlot storage) { // evm mapping slot: keccak256( abi.encode(<KEY>, <MAPPING_POSITION>) ) return StorageSlot.getBooleanSlot(keccak256(abi.encode(admin, _ADMIN_MAP_SLOT))); } function _set_admin_flag(address admin, bool flag) internal { if (admin != address(0)) { StorageSlot.BooleanSlot storage admin_slot = get_admin_slot(admin); if (admin_slot.value == flag) revert Adminship(); admin_slot.value = flag; } } function _transferAdminship(address old_admin, address new_admin) internal { _set_admin_flag(old_admin, false); _set_admin_flag(new_admin, true); emit AdminshipTransferred(old_admin, new_admin); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "contracts/utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.5) (utils/Multicall.sol) pragma solidity ^0.8.0; import "contracts/utils/Address.sol"; import "contracts/utils/Context.sol"; /** * @dev Provides a function to batch together multiple calls in a single external call. * * Consider any assumption about calldata validation performed by the sender may be violated if it's not especially * careful about sending transactions invoking {multicall}. For example, a relay address that filters function * selectors won't filter calls nested within a {multicall} operation. * * NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {_msgSender}). * If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data` * to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of * {_msgSender} are not propagated to subcalls. * * _Available since v4.1._ */ abstract contract Multicall is Context { /** * @dev Receives and executes a batch of function calls on this contract. * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) { bytes memory context = msg.sender == _msgSender() ? new bytes(0) : msg.data[msg.data.length - _contextSuffixLength():]; results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), bytes.concat(data[i], context)); } return results; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.0; import { Context } from "contracts/utils/Context.sol"; import { StorageSlot } from "contracts/utils/StorageSlot.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract SlotPausable is Context { // This is the keccak-256 hash of "pausable.slot" subtracted by 1 bytes32 private constant pausable_slot = 0xd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e5; function _paused() private view returns (bool) { return StorageSlot.getBooleanSlot(pausable_slot).value; } function _setPaused(bool flag) private { StorageSlot.getBooleanSlot(pausable_slot).value = flag; } /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ constructor() { _setPaused(false); } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused(); } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) revert EnforcedPause(); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) revert ExpectedPause(); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _setPaused(true); emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _setPaused(false); emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "contracts/interfaces/IEXBridge.sol"; import { Sig } from "contracts/interfaces/UniversalTypes.sol"; import { SlotServiceSigner } from "contracts/access/SlotServiceSigner.sol"; abstract contract CrossBridgeBase is IEXBridgeBase, SlotServiceSigner { uint32 constant public rateBase = 10000; address public feeAccount; address public syncAccount; BridgeContractInfo pairBridgeInfo; StakingInfo stakingInfo; FeeConfig feeConfig; BridgeAmountConfig bridgeAmountConfig; IEcoERC20 remoteToken; AssetInfo localAsset; uint64 public override localNonce; mapping(uint256 sourceNonce => bool filtered) public override filterSrcNonce; mapping(uint256 withdrawalId => address account) public override filterWithdrawalId; address public override remoteOracle; function _useLocalNonce() internal returns (uint64) { return localNonce++; } function setFeeAccount(address _feeAccount) public override onlyOwner { feeAccount = _feeAccount; } function setSyncAccount(address _syncAccount) public override onlyOwner { syncAccount = _syncAccount; } function setBridgePairInfo(BridgeContractInfo memory _pairBridgeInfo) public override onlyOwner { require(_pairBridgeInfo.bridge != address(0), "bridge address"); require(_pairBridgeInfo.chainId != 0, "bridge chain id"); require(_pairBridgeInfo.nonce == 0, "bridge nonce"); pairBridgeInfo = _pairBridgeInfo; } function setStakingInfo(StakingInfo memory _stakingInfo) public override onlyOwner { require(_stakingInfo.stake_contract != address(0), "stake contract"); require(_stakingInfo.ncpIds.length == 1, "ncpIds"); stakingInfo = _stakingInfo; } function setFeeConfig(FeeConfig memory _feeConfig) public override onlyOwner { require(_feeConfig.rate <= rateBase, "fee rate"); require(_feeConfig.min <= _feeConfig.max, "fee range"); feeConfig = _feeConfig; } function setBridgeAmountConfig(BridgeAmountConfig memory _bridgeAmountConfig) public override onlyOwner { require(_bridgeAmountConfig.min > 0, "bridge min"); require(_bridgeAmountConfig.min < _bridgeAmountConfig.max, "bridge range"); bridgeAmountConfig = _bridgeAmountConfig; } function setRemoteOracle(address _remoteOracle) public override onlyOwner { remoteOracle = _remoteOracle; } function getSrcBridgeContractInfo() external view override returns (BridgeContractInfo memory) { return pairBridgeInfo; } function getStakingInfo() external view override returns (StakingInfo memory) { return stakingInfo; } function getFeeConfig() external view override returns (FeeConfig memory) { return feeConfig; } function getBridgeAmountConfig() external view override returns (BridgeAmountConfig memory) { return bridgeAmountConfig; } function getLocalAsset() external view override returns (AssetInfo memory) { return localAsset; } function calcBridgeTransferAmount(uint256 amount) external view override returns (uint256 transferAmount, uint256 feeAmount) { return _calcBridgeTransferAmount(amount, feeConfig, bridgeAmountConfig); } function calcFee(uint256 amount) external view returns (uint256 feeAmount) { return _calcFee(amount, feeConfig); } function recoversToRemoteMessage( uint64 nonce, BridgeMessage memory msgToRemote, Sig[] memory sigs ) public view override returns (address[] memory signers) { BridgeContractInfo memory srcBridge = pairBridgeInfo; srcBridge.nonce = nonce; bytes32 msg_hash = keccak256(abi.encode(srcBridge, BrigeMessegeType.ToRemote, msgToRemote)); signers = new address[](sigs.length); for(uint256 i; i<sigs.length;) { signers[i] = ecrecover(msg_hash, sigs[i].v, sigs[i].r, sigs[i].s); unchecked { ++i; } } } function _verifyToRemoteMessage( uint64 nonce, BridgeMessage memory msgToRemote, Sig[] memory sigs ) internal view { checkQuorum( recoversToRemoteMessage(nonce, msgToRemote, sigs) ); } function recoversToOriginMessage( uint64 nonce, BridgeMessage memory msgToOrigin, Sig[] memory sigs ) public view override returns (address[] memory signers) { BridgeContractInfo memory srcBridge = pairBridgeInfo; srcBridge.nonce = nonce; bytes32 msg_hash = keccak256(abi.encode(srcBridge, BrigeMessegeType.ToOrigin, msgToOrigin)); signers = new address[](sigs.length); for(uint256 i; i<sigs.length;) { signers[i] = ecrecover(msg_hash, sigs[i].v, sigs[i].r, sigs[i].s); unchecked { ++i; } } } function _verifyToOriginMessage( uint64 nonce, BridgeMessage memory msgToOrigin, Sig[] memory sigs ) internal view { checkQuorum( recoversToOriginMessage(nonce, msgToOrigin, sigs) ); } function recoversSyncMessage( uint64 nonce, uint256 amount, Sig[] memory sigs ) public view override returns (address[] memory signers) { BridgeContractInfo memory srcBridge = pairBridgeInfo; srcBridge.nonce = nonce; bytes32 msg_hash = keccak256(abi.encode(srcBridge, BrigeMessegeType.Sync, amount)); signers = new address[](sigs.length); for(uint256 i; i<sigs.length;) { signers[i] = ecrecover(msg_hash, sigs[i].v, sigs[i].r, sigs[i].s); unchecked { ++i; } } } function _verifySyncMessage( uint64 nonce, uint256 amount, Sig[] memory sigs ) internal view { checkQuorum( recoversSyncMessage(nonce, amount, sigs) ); } function _getBridgeSnapshot() internal view returns (ConfigSnapshot memory snapshot) { snapshot.bridgeAmountConfig = bridgeAmountConfig; snapshot.feeConfig = feeConfig; snapshot.localAsset = localAsset; } function _updateAssetInfo(ConfigSnapshot memory snapshot) internal { _updateAssetInfo(snapshot.localAsset); } function _updateAssetInfo(AssetInfo memory _assetInfo) internal { localAsset = _assetInfo; } function _trySendValueCatchFail( address payable recipient, uint256 amount ) internal returns (bool success) { require(address(this).balance >= amount, "fail send value"); (success, ) = recipient.call{ value: amount }(hex""); if (!success) { emit FailSendValue(recipient, amount); (bool _success, ) = payable(owner()).call{ value: amount }(hex""); require(_success, "fail amount catch"); } } function _calcBridgeTransferAmount( uint256 amount, FeeConfig memory _feeConfig, BridgeAmountConfig memory _bridgeAmountConfig ) internal pure returns (uint256 transferAmount, uint256 feeAmount) { _checkBridgeTransferAmount(amount, _bridgeAmountConfig); feeAmount = _calcFee(amount, _feeConfig); require(amount > feeAmount, "fee amount"); transferAmount = amount - feeAmount; } function _calcFee(uint256 amount, FeeConfig memory _feeConfig) internal pure returns (uint256 feeAmount) { unchecked{ feeAmount = amount * _feeConfig.rate / rateBase; } if(feeAmount < _feeConfig.min) feeAmount = _feeConfig.min; if(feeAmount > _feeConfig.max) feeAmount = _feeConfig.max; } function _checkBridgeTransferAmount(uint256 amount, BridgeAmountConfig memory _bridgeAmountConfig) internal pure { require(_bridgeAmountConfig.min <= amount, "minimum"); require(_bridgeAmountConfig.max >= amount, "maximum"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAdminable, SlotAdminable } from "contracts/access/SlotAdminable.sol"; import { StorageSlot } from "contracts/utils/StorageSlot.sol"; interface ISlotServiceSigner is IAdminable { error SignerAuth(); event SignerAuthTransfer(address indexed previousSigner, address indexed newSigner); function signers(uint256 index) external returns (address); function getSigners() external returns (address[] memory); function isSigner(address signer) external returns (bool); function grantSigner(address signer) external; function revokeSigner(address signer) external; } struct AddressArraySlot { address[] signers; } struct AddressSlot { address signer; } library ServiceSignerSlot { /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function slotAddressArray(bytes32 slot) internal pure returns (address[] storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } function slotMappingToBoolean(bytes32 slot) internal pure returns (mapping(address => bool) storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } } library AddressArray { function remove(address[] storage arr, address data) internal { uint256 len = arr.length; for(uint256 i; i<len;) { if(data == arr[i]) { arr[i] = arr[len-1]; arr.pop(); return; } unchecked{ ++i; } } } } contract SlotServiceSigner is ISlotServiceSigner, SlotAdminable { // This is the keccak-256 hash of "service.signer.address.mapping.slot" subtracted by 1 // will use for array and mapping bytes32 private constant _SIGNER_SLOT = 0xf237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b; using ServiceSignerSlot for bytes32; using AddressArray for address[]; function signers(uint256 index) public view returns (address) { return _SIGNER_SLOT.slotAddressArray()[index]; } function signersLength() public view returns (uint256) { return _SIGNER_SLOT.slotAddressArray().length; } function getSigners() public view returns (address[] memory) { // todo: mutability bug? return _SIGNER_SLOT.slotAddressArray(); } function isSigner(address signer) public override view returns (bool) { return _SIGNER_SLOT.slotMappingToBoolean()[signer]; } function grantSigner(address signer) public override onlyAuthorized { _transferSignerAuth(address(0), signer); } function revokeSigner(address signer) public override onlyAuthorized { _transferSignerAuth(signer, address(0)); } function checkQuorum(address[] memory _signers) public view { uint256 len = _signers.length; // len >= total // 2 + 1 require(len >= (_SIGNER_SLOT.slotAddressArray().length >> 1) + 1, "quorum"); if(len > 1) { uint256 limit = len-1; for(uint256 i; i < limit;) { // avoid signature reuse require(_signers[i] < _signers[i+1], "Ascending Order"); unchecked{ ++i; } } } mapping(address => bool) storage signerMap = _SIGNER_SLOT.slotMappingToBoolean(); for(uint256 i; i < len;) { require(signerMap[ _signers[i] ], "invalid signer"); unchecked{ ++i; } } } function _getSignerMapSlot(address signer) internal pure returns (StorageSlot.BooleanSlot storage) { // evm mapping slot: keccak256( abi.encode(<KEY>, <MAPPING_POSITION>) ) return StorageSlot.getBooleanSlot(keccak256(abi.encode(signer, _SIGNER_SLOT))); } function _setSignerFlag(address signer, bool flag) internal { if (signer != address(0)) { if (_SIGNER_SLOT.slotMappingToBoolean()[signer] == flag) revert SignerAuth(); _SIGNER_SLOT.slotMappingToBoolean()[signer] = flag; if(flag) _SIGNER_SLOT.slotAddressArray().push( signer ); else _SIGNER_SLOT.slotAddressArray().remove( signer ); } } function _transferSignerAuth(address old_signer, address new_signer) internal { _setSignerFlag(old_signer, false); _setSignerFlag(new_signer, true); emit SignerAuthTransfer(old_signer, new_signer); } }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 1000000 }, "libraries": { "CrossBridgeOrigin.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"_stakingInfo","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Adminship","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"SignerAuth","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"ncpId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"CompleteFeeWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FailSendValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"ncpId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"ReceiveComplete","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"ncpId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReceivePending","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"ncpId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestFeeWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousSigner","type":"address"},{"indexed":true,"internalType":"address","name":"newSigner","type":"address"}],"name":"SignerAuthTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"localNonce","type":"uint64"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"srcNonce","type":"uint64"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ToOriginReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"localNonce","type":"uint64"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"ToRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calcBridgeTransferAmount","outputs":[{"internalType":"uint256","name":"transferAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calcFee","outputs":[{"internalType":"uint256","name":"feeAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"call","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_signers","type":"address[]"}],"name":"checkQuorum","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ncpId","type":"uint256"},{"internalType":"uint256","name":"withdrawalId","type":"uint256"}],"name":"completeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ncpId","type":"uint256"},{"internalType":"uint256","name":"withdrawalId","type":"uint256"}],"name":"completeWithrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sourceNonce","type":"uint256"}],"name":"filterSrcNonce","outputs":[{"internalType":"bool","name":"filtered","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"withdrawalId","type":"uint256"}],"name":"filterWithdrawalId","outputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBridgeAmountConfig","outputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint128","name":"toOriginNativeFee","type":"uint128"},{"internalType":"uint128","name":"toRemoteNativeSwapAmount","type":"uint128"}],"internalType":"struct BridgeAmountConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeConfig","outputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint32","name":"rate","type":"uint32"}],"internalType":"struct FeeConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLocalAsset","outputs":[{"components":[{"internalType":"uint128","name":"bridgeTotalLocked","type":"uint128"},{"internalType":"uint128","name":"bridgeTotalSyncStaking","type":"uint128"}],"internalType":"struct AssetInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSigners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSrcBridgeContractInfo","outputs":[{"components":[{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"address","name":"bridge","type":"address"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct BridgeContractInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingInfo","outputs":[{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"grantSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"grant_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"_stakingInfo","type":"tuple"}],"name":"initCrossBridgeOrigin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"is_admin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateBase","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"recoversSyncMessage","outputs":[{"internalType":"address[]","name":"signers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BridgeMessage","name":"msgToOrigin","type":"tuple"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"recoversToOriginMessage","outputs":[{"internalType":"address[]","name":"signers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BridgeMessage","name":"msgToRemote","type":"tuple"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"recoversToRemoteMessage","outputs":[{"internalType":"address[]","name":"signers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remoteOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceAdminship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"srcNonce","type":"uint64"},{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct BridgeMessage","name":"msgBridge","type":"tuple"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Sig[]","name":"sigs","type":"tuple[]"}],"name":"requestReceive","outputs":[{"internalType":"uint256[]","name":"withdrawalIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"requestWithdrawFee","outputs":[{"internalType":"uint256[]","name":"withdrawalIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"revokeSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"revoke_admin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint128","name":"toOriginNativeFee","type":"uint128"},{"internalType":"uint128","name":"toRemoteNativeSwapAmount","type":"uint128"}],"internalType":"struct BridgeAmountConfig","name":"_bridgeAmountConfig","type":"tuple"}],"name":"setBridgeAmountConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"chainId","type":"uint32"},{"internalType":"address","name":"bridge","type":"address"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct BridgeContractInfo","name":"_pairBridgeInfo","type":"tuple"}],"name":"setBridgePairInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAccount","type":"address"}],"name":"setFeeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint32","name":"rate","type":"uint32"}],"internalType":"struct FeeConfig","name":"_feeConfig","type":"tuple"}],"name":"setFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_remoteOracle","type":"address"}],"name":"setRemoteOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"stake_contract","type":"address"},{"internalType":"uint8[]","name":"ncpIds","type":"uint8[]"}],"internalType":"struct StakingInfo","name":"_stakingInfo","type":"tuple"}],"name":"setStakingInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_syncAccount","type":"address"}],"name":"setSyncAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"signers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signersLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"syncAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"toRemote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620064293803806200642983398101604081905262000034916200062c565b6200003f336200007c565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e5805460ff19169055620000748282620000c6565b50506200074c565b6000620000976000546201000090046001600160a01b031690565b9050620000a481620001fd565b15620000b757620000b781600062000214565b620000c28262000272565b5050565b600054610100900460ff1615808015620000e75750600054600160ff909116105b80620001035750303b15801562000103575060005460ff166001145b6200016c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000190576000805461ff0019166101001790555b6200019b336200007c565b620001a682620002d0565b620001b1836200007c565b8015620001f8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006200020a82620003a7565b5460ff1692915050565b6200022182600062000415565b6200022e81600162000415565b806001600160a01b0316826001600160a01b03167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b600080546001600160a01b038381166201000081810262010000600160b01b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b90565b620002da62000472565b80516001600160a01b0316620003245760405162461bcd60e51b815260206004820152600e60248201526d1cdd185ad94818dbdb9d1c9858dd60921b604482015260640162000163565b806020015151600114620003645760405162461bcd60e51b81526020600482015260066024820152656e637049647360d01b604482015260640162000163565b8051600480546001600160a01b0319166001600160a01b039092169190911781556020808301518051849392620003a192600592910190620004d7565b50505050565b604080516001600160a01b03831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b918101919091526000906200040f9060600160405160208183030381529060405280519060200120620002cd60201b60201c565b92915050565b6001600160a01b03821615620000c25760006200043283620003a7565b805490915082151560ff909116151503620004605760405163053db68960e51b815260040160405180910390fd5b805482151560ff199091161790555050565b6000546001600160a01b0362010000909104163314620004d55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000163565b565b82805482825590600052602060002090601f01602090048101928215620005725791602002820160005b838211156200054157835183826101000a81548160ff021916908360ff160217905550926020019260010160208160000104928301926001030262000501565b8015620005705782816101000a81549060ff021916905560010160208160000104928301926001030262000541565b505b506200058092915062000584565b5090565b5b8082111562000580576000815560010162000585565b80516001600160a01b0381168114620005b357600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620005f357620005f3620005b8565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006245762000624620005b8565b604052919050565b600080604083850312156200064057600080fd5b6200064b836200059b565b602084810151919350906001600160401b03808211156200066b57600080fd5b90850190604082880312156200068057600080fd5b6200068a620005ce565b62000695836200059b565b81528383015182811115620006a957600080fd5b80840193505087601f840112620006bf57600080fd5b825182811115620006d457620006d4620005b8565b8060051b9250620006e7858401620005f9565b818152928401850192858101908a8511156200070257600080fd5b948601945b8486101562000736578551925060ff83168314620007255760008081fd5b828252948601949086019062000707565b8087850152505050809450505050509250929050565b615ccd806200075c6000396000f3fe6080604052600436106103385760003560e01c806375dc7d8c116101b0578063b71c1179116100ec578063d1b4ae3a11610095578063e7bd37391161006f578063e7bd373914610be7578063f2fde38b14610c07578063f86276e614610c27578063fff6cae914610c4757600080fd5b8063d1b4ae3a14610b87578063d2a45ab514610ba7578063defb794e14610bc757600080fd5b8063c298ffa8116100c6578063c298ffa814610b1a578063c34b44a014610b3a578063ce0a7e7a14610b5a57600080fd5b8063b71c117914610ad2578063b88a802f14610ae5578063be83f92d14610afa57600080fd5b806394cf795e11610159578063aac132de11610133578063aac132de14610a43578063ac9650d814610a63578063b05e6a3514610a90578063b40cd21d14610ab057600080fd5b806394cf795e146109d65780639bed25d8146109eb578063a8edb3d114610a0057600080fd5b80638456cb591161018a5780638456cb59146109705780638da5cb5b14610985578063930ccaa6146109b657600080fd5b806375dc7d8c146108195780637df73e2714610839578063812db1be1461089e57600080fd5b80635c975abb1161027f57806363c724f7116102285780636dbf2fa0116102025780636dbf2fa0146107815780636f760d6c146107a2578063715018a6146107cf578063715bfe51146107e457600080fd5b806363c724f71461070757806363fa5c481461072757806365e17c9d1461075457600080fd5b8063615f32ed11610259578063615f32ed14610697578063628484ab146106b7578063629866b2146106e757600080fd5b80635c975abb146106155780635d3341851461063a5780635fbbc0d21461065a57600080fd5b80632ca3998d116102e15780634535b113116102bb5780634535b113146105315780634b023cf8146105515780635982fd201461057157600080fd5b80632ca3998d146104685780633f4ba83a146104de57806341f684f3146104f357600080fd5b80631ee93647116103125780631ee93647146103d65780632079fb9a146104035780632465e58e1461044857600080fd5b8063014e95ba1461034c57806308f496dd1461037c57806313cb35911461039c57600080fd5b3661034757610345610c4f565b005b600080fd5b34801561035857600080fd5b5061036261271081565b60405163ffffffff90911681526020015b60405180910390f35b34801561038857600080fd5b50610345610397366004614f6f565b610c90565b3480156103a857600080fd5b50600e546103bd9067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610373565b3480156103e257600080fd5b506103f66103f136600461513b565b610ca6565b60405161037391906151e1565b34801561040f57600080fd5b5061042361041e36600461522f565b610e7d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610373565b34801561045457600080fd5b50610345610463366004614f6f565b610ed9565b34801561047457600080fd5b50604080518082018252600080825260209182015281518083018352600d546fffffffffffffffffffffffffffffffff8082168084527001000000000000000000000000000000009092048116928401928352845191825291519091169181019190915201610373565b3480156104ea57600080fd5b50610345610f28565b3480156104ff57600080fd5b507ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b545b604051908152602001610373565b34801561053d57600080fd5b5061034561054c36600461525c565b610fc3565b34801561055d57600080fd5b5061034561056c366004614f6f565b611102565b34801561057d57600080fd5b506106086040805160608101825260008082526020820181905291810191909152506040805160608101825260035463ffffffff81168252640100000000810473ffffffffffffffffffffffffffffffffffffffff1660208301527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169181019190915290565b604051610373919061529c565b34801561062157600080fd5b5061062a611151565b6040519015158152602001610373565b34801561064657600080fd5b5061034561065536600461539a565b611183565b34801561066657600080fd5b5061066f61132a565b6040805182518152602080840151908201529181015163ffffffff1690820152606001610373565b3480156106a357600080fd5b506103456106b23660046153ea565b61137f565b3480156106c357600080fd5b5061062a6106d236600461522f565b600f6020526000908152604090205460ff1681565b3480156106f357600080fd5b5061034561070236600461543f565b6114da565b34801561071357600080fd5b50610345610722366004614f6f565b6115ff565b34801561073357600080fd5b506011546104239073ffffffffffffffffffffffffffffffffffffffff1681565b34801561076057600080fd5b506001546104239073ffffffffffffffffffffffffffffffffffffffff1681565b61079461078f3660046154b0565b61169d565b6040516103739291906155a7565b3480156107ae57600080fd5b506107c26107bd36600461513b565b611721565b60405161037391906155c2565b3480156107db57600080fd5b506103456118ff565b3480156107f057600080fd5b506108046107ff36600461522f565b611911565b60408051928352602083019190915201610373565b34801561082557600080fd5b5061052361083436600461522f565b6119a4565b34801561084557600080fd5b5061062a610854366004614f6f565b73ffffffffffffffffffffffffffffffffffffffff1660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205460ff1690565b3480156108aa57600080fd5b5061092760408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526009548152600a546020820152600b546fffffffffffffffffffffffffffffffff808216938301939093527001000000000000000000000000000000009004909116606082015290565b604080518251815260208084015190820152828201516fffffffffffffffffffffffffffffffff9081169282019290925260609283015190911691810191909152608001610373565b34801561097c57600080fd5b506103456119df565b34801561099157600080fd5b5060005462010000900473ffffffffffffffffffffffffffffffffffffffff16610423565b3480156109c257600080fd5b506103456109d13660046155fa565b611a7a565b3480156109e257600080fd5b506103f6611db4565b3480156109f757600080fd5b50610345611e42565b348015610a0c57600080fd5b50610423610a1b36600461522f565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610a4f57600080fd5b5061062a610a5e366004614f6f565b611e4d565b348015610a6f57600080fd5b50610a83610a7e36600461561c565b611e62565b6040516103739190615691565b348015610a9c57600080fd5b50610345610aab366004615713565b611f4a565b348015610abc57600080fd5b50610ac5612162565b6040516103739190615757565b610345610ae0366004614f6f565b612218565b348015610af157600080fd5b50610345612304565b348015610b0657600080fd5b50610345610b15366004614f6f565b612390565b348015610b2657600080fd5b50610345610b353660046157c8565b6123a3565b348015610b4657600080fd5b50610345610b55366004614f6f565b612620565b348015610b6657600080fd5b506002546104239073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b9357600080fd5b50610345610ba2366004614f6f565b6126be565b348015610bb357600080fd5b506103f6610bc236600461513b565b61270d565b348015610bd357600080fd5b50610345610be23660046155fa565b6128da565b348015610bf357600080fd5b506103f6610c02366004615862565b6128f0565b348015610c1357600080fd5b50610345610c22366004614f6f565b612abd565b348015610c3357600080fd5b506107c2610c4236600461522f565b612b71565b61034561303f565b610c57611151565b15610c8e576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b610c986131e5565b610ca360008261326d565b50565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff87168385015292519092600091610d0b9184916001918991016158de565b604051602081830303815290604052805190602001209050835167ffffffffffffffff811115610d3d57610d3d614fa9565b604051908082528060200260200182016040528015610d66578160200160208202803683370190505b50925060005b8451811015610e7357600182868381518110610d8a57610d8a61595c565b602002602001015160000151878481518110610da857610da861595c565b602002602001015160200151888581518110610dc657610dc661595c565b60200260200101516040015160405160008152602001604052604051610e08949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610e2a573d6000803e3d6000fd5b50505060206040510351848281518110610e4657610e4661595c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610d6c565b5050509392505050565b60007ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b8281548110610eb157610eb161595c565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1692915050565b610ee16131e5565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f3133611e4d565b80610f85575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fbb576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e6132e1565b610fcb6131e5565b61271063ffffffff16816040015163ffffffff16111561104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f666565207261746500000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6020810151815111156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6665652072616e676500000000000000000000000000000000000000000000006044820152606401611043565b8051600655602081015160075560400151600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091179055565b61110a6131e5565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061117e7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e55460ff1690565b905090565b600054610100900460ff16158080156111a35750600054600160ff909116105b806111bd5750303b1580156111bd575060005460ff166001145b611249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611043565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156112a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6112b03361337d565b6112b98261137f565b6112c28361337d565b801561132557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b61135460405180606001604052806000815260200160008152602001600063ffffffff1681525090565b50604080516060810182526006548152600754602082015260085463ffffffff169181019190915290565b6113876131e5565b805173ffffffffffffffffffffffffffffffffffffffff16611405576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520636f6e74726163740000000000000000000000000000000000006044820152606401611043565b806020015151600114611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e637049647300000000000000000000000000000000000000000000000000006044820152606401611043565b8051600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815560208083015180518493926114d492600592910190614e92565b50505050565b6114e26131e5565b805161154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f627269646765206d696e000000000000000000000000000000000000000000006044820152606401611043565b60208101518151106115b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6272696467652072616e676500000000000000000000000000000000000000006044820152606401611043565b80516009556020810151600a5560408101516060909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600b55565b61160833611e4d565b8061165c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611692576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca36000826133be565b600060606116a96131e5565b8573ffffffffffffffffffffffffffffffffffffffff168585856040516116d192919061598b565b60006040518083038185875af1925050503d806000811461170e576040519150601f19603f3d011682016040523d82523d6000602084013e611713565b606091505b509150915094509492505050565b606061172b610c4f565b67ffffffffffffffff84166000908152600f602052604090205460ff16156117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f737263206e6f6e636500000000000000000000000000000000000000000000006044820152606401611043565b67ffffffffffffffff84166000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556117f9613432565b905061180781868686613538565b6040820152611815846135f0565b9150611856816040015180516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526118f695808601939192908301828280156118e857602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116118b95790505b505050505081525050613a32565b50509392505050565b6119076131e5565b610c8e600061337d565b6040805160608082018352600654825260075460208084019190915260085463ffffffff168385015283516080810185526009548152600a5491810191909152600b546fffffffffffffffffffffffffffffffff80821695830195909552700100000000000000000000000000000000900490931690830152600091829161199b91859190613bbd565b91509150915091565b604080516060810182526006548152600754602082015260085463ffffffff16918101919091526000906119d9908390613c53565b92915050565b6119e833611e4d565b80611a3c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611a72576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e613c8d565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff163014611b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600081815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001546004805483517f83453945000000000000000000000000000000000000000000000000000000008152935173ffffffffffffffffffffffffffffffffffffffff938416969190931694909385936383453945938281019392829003018187875af1158015611bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd7919061599b565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b8152600401611c1191815260200190565b60e060405180830381865afa158015611c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5291906159b8565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b158015611cd057600080fd5b505af1158015611ce4573d6000803e3d6000fd5b50505050818147611cf59190615a71565b14611d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b84868573ffffffffffffffffffffffffffffffffffffffff167f7c74c89791d36692f3e6c457d3c7c0a625dd51bf7eb6a6a903008dfbd0c8ca8c60405160405180910390a4611dab8483613d06565b50505050505050565b60607ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b805480602002602001604051908101604052809291908181526020018280548015611e3857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611e0d575b5050505050905090565b610c8e33600061326d565b6000611e5882613f16565b5460ff1692915050565b6040805160008152602081019091526060908267ffffffffffffffff811115611e8d57611e8d614fa9565b604051908082528060200260200182016040528015611ec057816020015b6060815260200190600190039081611eab5790505b50915060005b83811015611f4257611f1d30868684818110611ee457611ee461595c565b9050602002810190611ef69190615a84565b85604051602001611f0993929190615ae9565b604051602081830303815290604052613f81565b838281518110611f2f57611f2f61595c565b6020908102919091010152600101611ec6565b505092915050565b611f526131e5565b602081015173ffffffffffffffffffffffffffffffffffffffff16611fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f62726964676520616464726573730000000000000000000000000000000000006044820152606401611043565b805163ffffffff16600003612044576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f62726964676520636861696e20696400000000000000000000000000000000006044820152606401611043565b604081015167ffffffffffffffff16156120ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f627269646765206e6f6e636500000000000000000000000000000000000000006044820152606401611043565b805160038054602084015160409094015167ffffffffffffffff1678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff909516640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921663ffffffff909416939093171792909216179055565b6040805180820190915260008152606060208201526040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815293949293838601939092919083018282801561220a57602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116121db5790505b505050505081525050905090565b612220610c4f565b73ffffffffffffffffffffffffffffffffffffffff811661223e5750335b6000612248613432565b90506122808160405180604001604052808573ffffffffffffffffffffffffffffffffffffffff168152602001348152506001613fad565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815261132595808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a32565b61230c610c4f565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152610ca395808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a32565b6123986131e5565b610ca381600061326d565b805160017ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b546123d5911c6001615b10565b81101561243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f71756f72756d00000000000000000000000000000000000000000000000000006044820152606401611043565b600181111561253d576000612454600183615a71565b905060005b8181101561253a578361246d826001615b10565b8151811061247d5761247d61595c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168482815181106124ad576124ad61595c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f417363656e64696e67204f7264657200000000000000000000000000000000006044820152606401611043565b600101612459565b50505b7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b60005b828110156114d45781600085838151811061257e5761257e61595c565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff16612618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964207369676e65720000000000000000000000000000000000006044820152606401611043565b600101612561565b61262933611e4d565b8061267d575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6126b3576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca38160006133be565b6126c66131e5565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff871683850152925190926000916127729184916002918991016158de565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156127a4576127a4614fa9565b6040519080825280602002602001820160405280156127cd578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106127f1576127f161595c565b60200260200101516000015187848151811061280f5761280f61595c565b60200260200101516020015188858151811061282d5761282d61595c565b6020026020010151604001516040516000815260200160405260405161286f949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612891573d6000803e3d6000fd5b505050602060405103518482815181106128ad576128ad61595c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016127d3565b6128e2610c4f565b6128ec8282614170565b5050565b60408051606080820183526003805463ffffffff81168452640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208085019190915267ffffffffffffffff881684860152935191936000926129559285929091899101615b23565b604051602081830303815290604052805190602001209050835167ffffffffffffffff81111561298757612987614fa9565b6040519080825280602002602001820160405280156129b0578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106129d4576129d461595c565b6020026020010151600001518784815181106129f2576129f261595c565b602002602001015160200151888581518110612a1057612a1061595c565b60200260200101516040015160405160008152602001604052604051612a52949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612a74573d6000803e3d6000fd5b50505060206040510351848281518110612a9057612a9061595c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016129b6565b612ac56131e5565b73ffffffffffffffffffffffffffffffffffffffff8116612b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401611043565b610ca38161337d565b6060612b7c33611e4d565b80612bd0575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612c06576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff9081168352600580548551602082810282018101909752818152929096169560009580860193929190830182828015612ca157602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612c725790505b50505091909252505081519192506000905080612cbe84886144a0565b915091506000805b835181101561303257828181518110612ce157612ce161595c565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e09818858381518110612d2b57612d2b61595c565b6020026020010151868481518110612d4557612d4561595c565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af1158015612dca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dee9190615b80565b838281518110612e0057612e0061595c565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff1660106000858481518110612e6057612e6061595c565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614612f0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b3060106000858481518110612f2157612f2161595c565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838181518110612f9957612f9961595c565b602002602001015160ff168773ffffffffffffffffffffffffffffffffffffffff167f9704c90fe671db4764d6a63750b9fa5c553824edb7df6027b79034dbc7543462858481518110612fee57612fee61595c565b6020026020010151856040516130229291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a3600101612cc6565b5090979650505050505050565b613047610c4f565b6000613051613432565b60025490915073ffffffffffffffffffffffffffffffffffffffff163381146130d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439060208082526004908201527f73796e6300000000000000000000000000000000000000000000000000000000604082015260600190565b6130e1346144b9565b3482604001516000018181516130f79190615b99565b6fffffffffffffffffffffffffffffffff1690525060408201516020018051349190613124908390615b99565b6fffffffffffffffffffffffffffffffff1690525060408201516131799080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006131836146a0565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f6a28c316db1c85974981164e2be540ab36fb82b391d0dfda369f948d1474de17346040516131d891815260200190565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff62010000909104163314610c8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611043565b6132788260006146e9565b6132838160016146e9565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b6132e9614786565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166133a581611e4d565b156133b5576133b581600061326d565b6128ec826147c4565b6133c9826000614842565b6133d4816001614842565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f9d188613a1a9a2ea26521bec252487f1739a344d8ffe6ef61cd7bca567d8f3d160405160405180910390a35050565b6134966040805160c08101825260006060808301828152608080850184905260a08501849052908452845190810185528281526020808201849052818601849052918101839052818401528351808501855282815290810191909152909182015290565b604080516080810182526009548152600a54602080830191909152600b546fffffffffffffffffffffffffffffffff80821684860152700100000000000000000000000000000000918290048116606080860191909152868401949094528451938401855260065484526007548484015260085463ffffffff168486015292855283518085018552600d54808516825291909104909216908201529082015290565b60408051808201909152600080825260208201526135578484846149fd565b60208301516040860151805161356e908390615bc2565b6fffffffffffffffffffffffffffffffff16905250825160208085015160405190815273ffffffffffffffffffffffffffffffffffffffff9092169167ffffffffffffffff8716917fca798eef187f833f790884379ed453edfc01901535dc3083866f8446dc25f0f8910160405180910390a35060408401515b949350505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152606095600095949381860193909183018282801561368557602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116136565790505b50505050508152505090506000816000015190506000806136aa8487602001516144a0565b915091506000805b8351811015613a26578281815181106136cd576136cd61595c565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e098188583815181106137175761371761595c565b60200260200101518684815181106137315761373161595c565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af11580156137b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137da9190615b80565b8382815181106137ec576137ec61595c565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff166010600085848151811061384c5761384c61595c565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff16146138f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b8760000151601060008584815181106139115761391161595c565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508381815181106139895761398961595c565b602002602001015160ff16886000015173ffffffffffffffffffffffffffffffffffffffff167f4833244c0517cc1688428ff8842d0c253c9cea94b95f61d91a680203b55ebf018584815181106139e2576139e261595c565b602002602001015185604051613a169291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a36001016136b2565b50909695505050505050565b60025460009073ffffffffffffffffffffffffffffffffffffffff1680613ab5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f73796e63207a65726f00000000000000000000000000000000000000000000006044820152606401611043565b825173ffffffffffffffffffffffffffffffffffffffff821631925060005b846020015151811015613b9b578173ffffffffffffffffffffffffffffffffffffffff1663ddd5e1b286602001518381518110613b1357613b1361595c565b6020026020010151856040518363ffffffff1660e01b8152600401613b5d92919060ff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015613b7757600080fd5b505af1158015613b8b573d6000803e3d6000fd5b505060019092019150613ad49050565b506135e88373ffffffffffffffffffffffffffffffffffffffff841631615a71565b600080613bca8584614a0b565b613bd48585613c53565b9050808511613c3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b613c498186615a71565b9150935093915050565b6040810151815161271063ffffffff90921684029190910490811015613c77575080515b81602001518111156119d9575060200151919050565b613c95610c4f565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833613353565b600081471015613d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6661696c2073656e642076616c756500000000000000000000000000000000006044820152606401611043565b60405173ffffffffffffffffffffffffffffffffffffffff8416908390600081818185875af1925050503d8060008114613dc8576040519150601f19603f3d011682016040523d82523d6000602084013e613dcd565b606091505b505080915050806119d9578273ffffffffffffffffffffffffffffffffffffffff167f7a8da3fbf14e43fbfd79d8ce7ab913a13000dbbd248e9442988476e9e4b94cd883604051613e2091815260200190565b60405180910390a26000805462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114613e9f576040519150601f19603f3d011682016040523d82523d6000602084013e613ea4565b606091505b5050905080613f0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6661696c20616d6f756e742063617463680000000000000000000000000000006044820152606401611043565b5092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b918101919091526000906119d9906060016040516020818303038152906040528051906020012090565b6060613fa68383604051806060016040528060278152602001615c7160279139614ae4565b9392505050565b6000613fc183602001518560200151614a0b565b811561407857613fd983602001518560000151613c53565b905080836020015111614048576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b60208301805182900390526001546140769073ffffffffffffffffffffffffffffffffffffffff1682613d06565b505b60208301516040850151805161408f908390615b99565b6fffffffffffffffffffffffffffffffff1690525060408401516140e49080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006140ee6146a0565b9050836000015173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f87c8e141595387353b9f5800de2510b7678d07b38c7e01c29ab619d7938e6396866020015185604051614154929190918252602082015260400190565b60405180910390a361416984602001516144b9565b5050505050565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff16806141fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600082815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556004805482517f83453945000000000000000000000000000000000000000000000000000000008152925173ffffffffffffffffffffffffffffffffffffffff909116949385936383453945938181019391829003018187875af115801561429f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c3919061599b565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b81526004016142fd91815260200190565b60e060405180830381865afa15801561431a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061433e91906159b8565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b1580156143bc57600080fd5b505af11580156143d0573d6000803e3d6000fd5b505050508181476143e19190615a71565b14614448576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b6144528483613d06565b5084868573ffffffffffffffffffffffffffffffffffffffff167f56938cd8bd3b7e9e03d3414d2307365bc79aa14190fc2b22e7119ad2ba26c48160405160405180910390a4505050505050565b6060806144ad8484614b69565b915091505b9250929050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526000958086019391929083018282801561454a57602002820191906000526020600020906000905b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161451b5790505b505050919092525050815191925060009050806145678486614b69565b9150915060005b8251811015614698578373ffffffffffffffffffffffffffffffffffffffff16636366ebe38383815181106145a5576145a561595c565b60200260200101516fffffffffffffffffffffffffffffffff168584815181106145d1576145d161595c565b60200260200101518585815181106145eb576145eb61595c565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260ff90921660048301526fffffffffffffffffffffffffffffffff166024820152306044820152600060648201819052608482015260a4016000604051808303818588803b15801561467357600080fd5b505af1158015614687573d6000803e3d6000fd5b50506001909301925061456e915050565b505050505050565b600e805460009167ffffffffffffffff90911690826146be83615beb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905090565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec57600061471083613f16565b805490915082151560ff909116151503614756576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80548215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790555050565b61478e611151565b610c8e576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec5773ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205481151560ff9091161515036148e4576040517fd4be6f0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682158015919091179091556149d3577ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80546001810182556000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555050565b6128ec7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b83614c51565b611325610b3584848461270d565b8051821015614a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d696e696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b81816020015110156128ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d6178696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051614b0e9190615c12565b600060405180830381855af49150503d8060008114614b49576040519150601f19603f3d011682016040523d82523d6000602084013e614b4e565b606091505b5091509150614b5f86838387614db3565b9695505050505050565b606080836020015151600114614bdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f64656661756c74206e63704964000000000000000000000000000000000000006044820152606401611043565b60208401516040805160018082528183019092529193508160200160208202803683370190505090508281600081518110614c1857614c1861595c565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff16815250509250929050565b815460005b818110156114d457838181548110614c7057614c7061595c565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff90811690841603614dab5783614ca8600184615a71565b81548110614cb857614cb861595c565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848281548110614cf557614cf561595c565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083805480614d4d57614d4d615c2e565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b600101614c56565b60608315614e49578251600003614e425773ffffffffffffffffffffffffffffffffffffffff85163b614e42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611043565b50816135e8565b6135e88383815115614e5e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439190615c5d565b82805482825590600052602060002090601f01602090048101928215614f285791602002820160005b83821115614ef957835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614ebb565b8015614f265782816101000a81549060ff0219169055600101602081600001049283019260010302614ef9565b505b50614f34929150614f38565b5090565b5b80821115614f345760008155600101614f39565b73ffffffffffffffffffffffffffffffffffffffff81168114610ca357600080fd5b600060208284031215614f8157600080fd5b8135613fa681614f4d565b803567ffffffffffffffff81168114614fa457600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715614ffb57614ffb614fa9565b60405290565b6040805190810167ffffffffffffffff81118282101715614ffb57614ffb614fa9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561506b5761506b614fa9565b604052919050565b600067ffffffffffffffff82111561508d5761508d614fa9565b5060051b60200190565b803560ff81168114614fa457600080fd5b600082601f8301126150b957600080fd5b813560206150ce6150c983615073565b615024565b828152606092830285018201928282019190878511156150ed57600080fd5b8387015b858110156130325781818a0312156151095760008081fd5b615111614fd8565b61511a82615097565b815281860135868201526040808301359082015284529284019281016150f1565b6000806000838503608081121561515157600080fd5b61515a85614f8c565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561518c57600080fd5b50615195615001565b60208501356151a381614f4d565b8152604085013560208201529150606084013567ffffffffffffffff8111156151cb57600080fd5b6151d7868287016150a8565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b81811015613a2657835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016151fd565b60006020828403121561524157600080fd5b5035919050565b803563ffffffff81168114614fa457600080fd5b60006060828403121561526e57600080fd5b615276614fd8565b823581526020830135602082015261529060408401615248565b60408201529392505050565b815163ffffffff16815260208083015173ffffffffffffffffffffffffffffffffffffffff169082015260408083015167ffffffffffffffff1690820152606081016119d9565b6000604082840312156152f557600080fd5b6152fd615001565b9050813561530a81614f4d565b815260208281013567ffffffffffffffff81111561532757600080fd5b8301601f8101851361533857600080fd5b80356153466150c982615073565b81815260059190911b8201830190838101908783111561536557600080fd5b928401925b8284101561538a5761537b84615097565b8252928401929084019061536a565b8085870152505050505092915050565b600080604083850312156153ad57600080fd5b82356153b881614f4d565b9150602083013567ffffffffffffffff8111156153d457600080fd5b6153e0858286016152e3565b9150509250929050565b6000602082840312156153fc57600080fd5b813567ffffffffffffffff81111561541357600080fd5b6135e8848285016152e3565b80356fffffffffffffffffffffffffffffffff81168114614fa457600080fd5b60006080828403121561545157600080fd5b6040516080810181811067ffffffffffffffff8211171561547457615474614fa9565b806040525082358152602083013560208201526154936040840161541f565b60408201526154a46060840161541f565b60608201529392505050565b600080600080606085870312156154c657600080fd5b84356154d181614f4d565b935060208501359250604085013567ffffffffffffffff808211156154f557600080fd5b818701915087601f83011261550957600080fd5b81358181111561551857600080fd5b88602082850101111561552a57600080fd5b95989497505060200194505050565b60005b8381101561555457818101518382015260200161553c565b50506000910152565b60008151808452615575816020860160208601615539565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006135e8604083018461555d565b6020808252825182820181905260009190848201906040850190845b81811015613a26578351835292840192918401916001016155de565b6000806040838503121561560d57600080fd5b50508035926020909101359150565b6000806020838503121561562f57600080fd5b823567ffffffffffffffff8082111561564757600080fd5b818501915085601f83011261565b57600080fd5b81358181111561566a57600080fd5b8660208260051b850101111561567f57600080fd5b60209290920196919550909350505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015615706577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526156f485835161555d565b945092850192908501906001016156ba565b5092979650505050505050565b60006060828403121561572557600080fd5b61572d614fd8565b61573683615248565b8152602083013561574681614f4d565b602082015261529060408401614f8c565b6020808252825173ffffffffffffffffffffffffffffffffffffffff16828201528281015160408084015280516060840181905260009291820190839060808601905b808310156157bd57835160ff16825292840192600192909201919084019061579a565b509695505050505050565b600060208083850312156157db57600080fd5b823567ffffffffffffffff8111156157f257600080fd5b8301601f8101851361580357600080fd5b80356158116150c982615073565b81815260059190911b8201830190838101908783111561583057600080fd5b928401925b8284101561585757833561584881614f4d565b82529284019290840190615835565b979650505050505050565b60008060006060848603121561587757600080fd5b61588084614f8c565b925060208401359150604084013567ffffffffffffffff8111156151cb57600080fd5b600481106158da577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260c0810161592d60608301856158a3565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183823760009101908152919050565b6000602082840312156159ad57600080fd5b8151613fa681614f4d565b600060e082840312156159ca57600080fd5b60405160e0810181811067ffffffffffffffff821117156159ed576159ed614fa9565b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151615a3681614f4d565b60c08201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156119d9576119d9615a42565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615ab957600080fd5b83018035915067ffffffffffffffff821115615ad457600080fd5b6020019150368190038213156144b257600080fd5b828482376000838201600081528351615b06818360208801615539565b0195945050505050565b808201808211156119d9576119d9615a42565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260a08101615b7260608301856158a3565b826080830152949350505050565b600060208284031215615b9257600080fd5b5051919050565b6fffffffffffffffffffffffffffffffff818116838216019080821115613f0f57613f0f615a42565b6fffffffffffffffffffffffffffffffff828116828216039080821115613f0f57613f0f615a42565b600067ffffffffffffffff808316818103615c0857615c08615a42565b6001019392505050565b60008251615c24818460208701615539565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000613fa6602083018461555d56fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209c771ad8a1e0b048b08be8f0d36d466b7655b6a8b9fede21ff34f40f4ef3f6da64736f6c634300081700330000000000000000000000007d76ae60dcc2fdb57d3924024e2ad940b76ef81f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000006af09e1a3c886dd8560bf4cabd65db16ea2724d8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000029
Deployed Bytecode
0x6080604052600436106103385760003560e01c806375dc7d8c116101b0578063b71c1179116100ec578063d1b4ae3a11610095578063e7bd37391161006f578063e7bd373914610be7578063f2fde38b14610c07578063f86276e614610c27578063fff6cae914610c4757600080fd5b8063d1b4ae3a14610b87578063d2a45ab514610ba7578063defb794e14610bc757600080fd5b8063c298ffa8116100c6578063c298ffa814610b1a578063c34b44a014610b3a578063ce0a7e7a14610b5a57600080fd5b8063b71c117914610ad2578063b88a802f14610ae5578063be83f92d14610afa57600080fd5b806394cf795e11610159578063aac132de11610133578063aac132de14610a43578063ac9650d814610a63578063b05e6a3514610a90578063b40cd21d14610ab057600080fd5b806394cf795e146109d65780639bed25d8146109eb578063a8edb3d114610a0057600080fd5b80638456cb591161018a5780638456cb59146109705780638da5cb5b14610985578063930ccaa6146109b657600080fd5b806375dc7d8c146108195780637df73e2714610839578063812db1be1461089e57600080fd5b80635c975abb1161027f57806363c724f7116102285780636dbf2fa0116102025780636dbf2fa0146107815780636f760d6c146107a2578063715018a6146107cf578063715bfe51146107e457600080fd5b806363c724f71461070757806363fa5c481461072757806365e17c9d1461075457600080fd5b8063615f32ed11610259578063615f32ed14610697578063628484ab146106b7578063629866b2146106e757600080fd5b80635c975abb146106155780635d3341851461063a5780635fbbc0d21461065a57600080fd5b80632ca3998d116102e15780634535b113116102bb5780634535b113146105315780634b023cf8146105515780635982fd201461057157600080fd5b80632ca3998d146104685780633f4ba83a146104de57806341f684f3146104f357600080fd5b80631ee93647116103125780631ee93647146103d65780632079fb9a146104035780632465e58e1461044857600080fd5b8063014e95ba1461034c57806308f496dd1461037c57806313cb35911461039c57600080fd5b3661034757610345610c4f565b005b600080fd5b34801561035857600080fd5b5061036261271081565b60405163ffffffff90911681526020015b60405180910390f35b34801561038857600080fd5b50610345610397366004614f6f565b610c90565b3480156103a857600080fd5b50600e546103bd9067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610373565b3480156103e257600080fd5b506103f66103f136600461513b565b610ca6565b60405161037391906151e1565b34801561040f57600080fd5b5061042361041e36600461522f565b610e7d565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610373565b34801561045457600080fd5b50610345610463366004614f6f565b610ed9565b34801561047457600080fd5b50604080518082018252600080825260209182015281518083018352600d546fffffffffffffffffffffffffffffffff8082168084527001000000000000000000000000000000009092048116928401928352845191825291519091169181019190915201610373565b3480156104ea57600080fd5b50610345610f28565b3480156104ff57600080fd5b507ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b545b604051908152602001610373565b34801561053d57600080fd5b5061034561054c36600461525c565b610fc3565b34801561055d57600080fd5b5061034561056c366004614f6f565b611102565b34801561057d57600080fd5b506106086040805160608101825260008082526020820181905291810191909152506040805160608101825260035463ffffffff81168252640100000000810473ffffffffffffffffffffffffffffffffffffffff1660208301527801000000000000000000000000000000000000000000000000900467ffffffffffffffff169181019190915290565b604051610373919061529c565b34801561062157600080fd5b5061062a611151565b6040519015158152602001610373565b34801561064657600080fd5b5061034561065536600461539a565b611183565b34801561066657600080fd5b5061066f61132a565b6040805182518152602080840151908201529181015163ffffffff1690820152606001610373565b3480156106a357600080fd5b506103456106b23660046153ea565b61137f565b3480156106c357600080fd5b5061062a6106d236600461522f565b600f6020526000908152604090205460ff1681565b3480156106f357600080fd5b5061034561070236600461543f565b6114da565b34801561071357600080fd5b50610345610722366004614f6f565b6115ff565b34801561073357600080fd5b506011546104239073ffffffffffffffffffffffffffffffffffffffff1681565b34801561076057600080fd5b506001546104239073ffffffffffffffffffffffffffffffffffffffff1681565b61079461078f3660046154b0565b61169d565b6040516103739291906155a7565b3480156107ae57600080fd5b506107c26107bd36600461513b565b611721565b60405161037391906155c2565b3480156107db57600080fd5b506103456118ff565b3480156107f057600080fd5b506108046107ff36600461522f565b611911565b60408051928352602083019190915201610373565b34801561082557600080fd5b5061052361083436600461522f565b6119a4565b34801561084557600080fd5b5061062a610854366004614f6f565b73ffffffffffffffffffffffffffffffffffffffff1660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205460ff1690565b3480156108aa57600080fd5b5061092760408051608081018252600080825260208201819052918101829052606081019190915250604080516080810182526009548152600a546020820152600b546fffffffffffffffffffffffffffffffff808216938301939093527001000000000000000000000000000000009004909116606082015290565b604080518251815260208084015190820152828201516fffffffffffffffffffffffffffffffff9081169282019290925260609283015190911691810191909152608001610373565b34801561097c57600080fd5b506103456119df565b34801561099157600080fd5b5060005462010000900473ffffffffffffffffffffffffffffffffffffffff16610423565b3480156109c257600080fd5b506103456109d13660046155fa565b611a7a565b3480156109e257600080fd5b506103f6611db4565b3480156109f757600080fd5b50610345611e42565b348015610a0c57600080fd5b50610423610a1b36600461522f565b60106020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610a4f57600080fd5b5061062a610a5e366004614f6f565b611e4d565b348015610a6f57600080fd5b50610a83610a7e36600461561c565b611e62565b6040516103739190615691565b348015610a9c57600080fd5b50610345610aab366004615713565b611f4a565b348015610abc57600080fd5b50610ac5612162565b6040516103739190615757565b610345610ae0366004614f6f565b612218565b348015610af157600080fd5b50610345612304565b348015610b0657600080fd5b50610345610b15366004614f6f565b612390565b348015610b2657600080fd5b50610345610b353660046157c8565b6123a3565b348015610b4657600080fd5b50610345610b55366004614f6f565b612620565b348015610b6657600080fd5b506002546104239073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b9357600080fd5b50610345610ba2366004614f6f565b6126be565b348015610bb357600080fd5b506103f6610bc236600461513b565b61270d565b348015610bd357600080fd5b50610345610be23660046155fa565b6128da565b348015610bf357600080fd5b506103f6610c02366004615862565b6128f0565b348015610c1357600080fd5b50610345610c22366004614f6f565b612abd565b348015610c3357600080fd5b506107c2610c4236600461522f565b612b71565b61034561303f565b610c57611151565b15610c8e576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b610c986131e5565b610ca360008261326d565b50565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff87168385015292519092600091610d0b9184916001918991016158de565b604051602081830303815290604052805190602001209050835167ffffffffffffffff811115610d3d57610d3d614fa9565b604051908082528060200260200182016040528015610d66578160200160208202803683370190505b50925060005b8451811015610e7357600182868381518110610d8a57610d8a61595c565b602002602001015160000151878481518110610da857610da861595c565b602002602001015160200151888581518110610dc657610dc661595c565b60200260200101516040015160405160008152602001604052604051610e08949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610e2a573d6000803e3d6000fd5b50505060206040510351848281518110610e4657610e4661595c565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152600101610d6c565b5050509392505050565b60007ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b8281548110610eb157610eb161595c565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1692915050565b610ee16131e5565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610f3133611e4d565b80610f85575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610fbb576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e6132e1565b610fcb6131e5565b61271063ffffffff16816040015163ffffffff16111561104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f666565207261746500000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6020810151815111156110bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6665652072616e676500000000000000000000000000000000000000000000006044820152606401611043565b8051600655602081015160075560400151600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff909216919091179055565b61110a6131e5565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061117e7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e55460ff1690565b905090565b600054610100900460ff16158080156111a35750600054600160ff909116105b806111bd5750303b1580156111bd575060005460ff166001145b611249576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611043565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156112a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6112b03361337d565b6112b98261137f565b6112c28361337d565b801561132557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b61135460405180606001604052806000815260200160008152602001600063ffffffff1681525090565b50604080516060810182526006548152600754602082015260085463ffffffff169181019190915290565b6113876131e5565b805173ffffffffffffffffffffffffffffffffffffffff16611405576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520636f6e74726163740000000000000000000000000000000000006044820152606401611043565b806020015151600114611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f6e637049647300000000000000000000000000000000000000000000000000006044820152606401611043565b8051600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117815560208083015180518493926114d492600592910190614e92565b50505050565b6114e26131e5565b805161154a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f627269646765206d696e000000000000000000000000000000000000000000006044820152606401611043565b60208101518151106115b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6272696467652072616e676500000000000000000000000000000000000000006044820152606401611043565b80516009556020810151600a5560408101516060909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600b55565b61160833611e4d565b8061165c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611692576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca36000826133be565b600060606116a96131e5565b8573ffffffffffffffffffffffffffffffffffffffff168585856040516116d192919061598b565b60006040518083038185875af1925050503d806000811461170e576040519150601f19603f3d011682016040523d82523d6000602084013e611713565b606091505b509150915094509492505050565b606061172b610c4f565b67ffffffffffffffff84166000908152600f602052604090205460ff16156117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f737263206e6f6e636500000000000000000000000000000000000000000000006044820152606401611043565b67ffffffffffffffff84166000908152600f6020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556117f9613432565b905061180781868686613538565b6040820152611815846135f0565b9150611856816040015180516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526118f695808601939192908301828280156118e857602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116118b95790505b505050505081525050613a32565b50509392505050565b6119076131e5565b610c8e600061337d565b6040805160608082018352600654825260075460208084019190915260085463ffffffff168385015283516080810185526009548152600a5491810191909152600b546fffffffffffffffffffffffffffffffff80821695830195909552700100000000000000000000000000000000900490931690830152600091829161199b91859190613bbd565b91509150915091565b604080516060810182526006548152600754602082015260085463ffffffff16918101919091526000906119d9908390613c53565b92915050565b6119e833611e4d565b80611a3c575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611a72576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8e613c8d565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff163014611b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600081815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556001546004805483517f83453945000000000000000000000000000000000000000000000000000000008152935173ffffffffffffffffffffffffffffffffffffffff938416969190931694909385936383453945938281019392829003018187875af1158015611bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd7919061599b565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b8152600401611c1191815260200190565b60e060405180830381865afa158015611c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5291906159b8565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b158015611cd057600080fd5b505af1158015611ce4573d6000803e3d6000fd5b50505050818147611cf59190615a71565b14611d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b84868573ffffffffffffffffffffffffffffffffffffffff167f7c74c89791d36692f3e6c457d3c7c0a625dd51bf7eb6a6a903008dfbd0c8ca8c60405160405180910390a4611dab8483613d06565b50505050505050565b60607ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b805480602002602001604051908101604052809291908181526020018280548015611e3857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611e0d575b5050505050905090565b610c8e33600061326d565b6000611e5882613f16565b5460ff1692915050565b6040805160008152602081019091526060908267ffffffffffffffff811115611e8d57611e8d614fa9565b604051908082528060200260200182016040528015611ec057816020015b6060815260200190600190039081611eab5790505b50915060005b83811015611f4257611f1d30868684818110611ee457611ee461595c565b9050602002810190611ef69190615a84565b85604051602001611f0993929190615ae9565b604051602081830303815290604052613f81565b838281518110611f2f57611f2f61595c565b6020908102919091010152600101611ec6565b505092915050565b611f526131e5565b602081015173ffffffffffffffffffffffffffffffffffffffff16611fd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f62726964676520616464726573730000000000000000000000000000000000006044820152606401611043565b805163ffffffff16600003612044576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f62726964676520636861696e20696400000000000000000000000000000000006044820152606401611043565b604081015167ffffffffffffffff16156120ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f627269646765206e6f6e636500000000000000000000000000000000000000006044820152606401611043565b805160038054602084015160409094015167ffffffffffffffff1678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff909516640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921663ffffffff909416939093171792909216179055565b6040805180820190915260008152606060208201526040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815293949293838601939092919083018282801561220a57602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116121db5790505b505050505081525050905090565b612220610c4f565b73ffffffffffffffffffffffffffffffffffffffff811661223e5750335b6000612248613432565b90506122808160405180604001604052808573ffffffffffffffffffffffffffffffffffffffff168152602001348152506001613fad565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff16825260058054845160208281028201810190965281815261132595808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a32565b61230c610c4f565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152610ca395808601939192908301828280156118e8576000918252602091829020805460ff1684529082028301929091600191018084116118b9579050505050505081525050613a32565b6123986131e5565b610ca381600061326d565b805160017ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b546123d5911c6001615b10565b81101561243e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f71756f72756d00000000000000000000000000000000000000000000000000006044820152606401611043565b600181111561253d576000612454600183615a71565b905060005b8181101561253a578361246d826001615b10565b8151811061247d5761247d61595c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168482815181106124ad576124ad61595c565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1610612532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f417363656e64696e67204f7264657200000000000000000000000000000000006044820152606401611043565b600101612459565b50505b7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b60005b828110156114d45781600085838151811061257e5761257e61595c565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff16612618576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964207369676e65720000000000000000000000000000000000006044820152606401611043565b600101612561565b61262933611e4d565b8061267d575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6126b3576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ca38160006133be565b6126c66131e5565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b604080516060808201835260035463ffffffff81168352640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208084019190915267ffffffffffffffff871683850152925190926000916127729184916002918991016158de565b604051602081830303815290604052805190602001209050835167ffffffffffffffff8111156127a4576127a4614fa9565b6040519080825280602002602001820160405280156127cd578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106127f1576127f161595c565b60200260200101516000015187848151811061280f5761280f61595c565b60200260200101516020015188858151811061282d5761282d61595c565b6020026020010151604001516040516000815260200160405260405161286f949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612891573d6000803e3d6000fd5b505050602060405103518482815181106128ad576128ad61595c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016127d3565b6128e2610c4f565b6128ec8282614170565b5050565b60408051606080820183526003805463ffffffff81168452640100000000900473ffffffffffffffffffffffffffffffffffffffff1660208085019190915267ffffffffffffffff881684860152935191936000926129559285929091899101615b23565b604051602081830303815290604052805190602001209050835167ffffffffffffffff81111561298757612987614fa9565b6040519080825280602002602001820160405280156129b0578160200160208202803683370190505b50925060005b8451811015610e73576001828683815181106129d4576129d461595c565b6020026020010151600001518784815181106129f2576129f261595c565b602002602001015160200151888581518110612a1057612a1061595c565b60200260200101516040015160405160008152602001604052604051612a52949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612a74573d6000803e3d6000fd5b50505060206040510351848281518110612a9057612a9061595c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526001016129b6565b612ac56131e5565b73ffffffffffffffffffffffffffffffffffffffff8116612b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401611043565b610ca38161337d565b6060612b7c33611e4d565b80612bd0575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612c06576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff9081168352600580548551602082810282018101909752818152929096169560009580860193929190830182828015612ca157602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411612c725790505b50505091909252505081519192506000905080612cbe84886144a0565b915091506000805b835181101561303257828181518110612ce157612ce161595c565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e09818858381518110612d2b57612d2b61595c565b6020026020010151868481518110612d4557612d4561595c565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af1158015612dca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dee9190615b80565b838281518110612e0057612e0061595c565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff1660106000858481518110612e6057612e6061595c565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1614612f0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b3060106000858481518110612f2157612f2161595c565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838181518110612f9957612f9961595c565b602002602001015160ff168773ffffffffffffffffffffffffffffffffffffffff167f9704c90fe671db4764d6a63750b9fa5c553824edb7df6027b79034dbc7543462858481518110612fee57612fee61595c565b6020026020010151856040516130229291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a3600101612cc6565b5090979650505050505050565b613047610c4f565b6000613051613432565b60025490915073ffffffffffffffffffffffffffffffffffffffff163381146130d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439060208082526004908201527f73796e6300000000000000000000000000000000000000000000000000000000604082015260600190565b6130e1346144b9565b3482604001516000018181516130f79190615b99565b6fffffffffffffffffffffffffffffffff1690525060408201516020018051349190613124908390615b99565b6fffffffffffffffffffffffffffffffff1690525060408201516131799080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006131836146a0565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f6a28c316db1c85974981164e2be540ab36fb82b391d0dfda369f948d1474de17346040516131d891815260200190565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff62010000909104163314610c8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611043565b6132788260006146e9565b6132838160016146e9565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621360405160405180910390a35050565b6132e9614786565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff166133a581611e4d565b156133b5576133b581600061326d565b6128ec826147c4565b6133c9826000614842565b6133d4816001614842565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f9d188613a1a9a2ea26521bec252487f1739a344d8ffe6ef61cd7bca567d8f3d160405160405180910390a35050565b6134966040805160c08101825260006060808301828152608080850184905260a08501849052908452845190810185528281526020808201849052818601849052918101839052818401528351808501855282815290810191909152909182015290565b604080516080810182526009548152600a54602080830191909152600b546fffffffffffffffffffffffffffffffff80821684860152700100000000000000000000000000000000918290048116606080860191909152868401949094528451938401855260065484526007548484015260085463ffffffff168486015292855283518085018552600d54808516825291909104909216908201529082015290565b60408051808201909152600080825260208201526135578484846149fd565b60208301516040860151805161356e908390615bc2565b6fffffffffffffffffffffffffffffffff16905250825160208085015160405190815273ffffffffffffffffffffffffffffffffffffffff9092169167ffffffffffffffff8716917fca798eef187f833f790884379ed453edfc01901535dc3083866f8446dc25f0f8910160405180910390a35060408401515b949350505050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff168252600580548451602082810282018101909652818152606095600095949381860193909183018282801561368557602002820191906000526020600020906000905b825461010083900a900460ff168152602060019283018181049485019490930390920291018084116136565790505b50505050508152505090506000816000015190506000806136aa8487602001516144a0565b915091506000805b8351811015613a26578281815181106136cd576136cd61595c565b60200260200101516fffffffffffffffffffffffffffffffff1691508473ffffffffffffffffffffffffffffffffffffffff1663e4e098188583815181106137175761371761595c565b60200260200101518684815181106137315761373161595c565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260ff9283166004820152911660248201526044810185905230606482015260006084820181905260a482015260c4016020604051808303816000875af11580156137b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137da9190615b80565b8382815181106137ec576137ec61595c565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050600073ffffffffffffffffffffffffffffffffffffffff166010600085848151811061384c5761384c61595c565b6020908102919091018101516fffffffffffffffffffffffffffffffff1682528101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff16146138f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f7769746864726177616c496400000000000000000000000000000000000000006044820152606401611043565b8760000151601060008584815181106139115761391161595c565b60200260200101516fffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508381815181106139895761398961595c565b602002602001015160ff16886000015173ffffffffffffffffffffffffffffffffffffffff167f4833244c0517cc1688428ff8842d0c253c9cea94b95f61d91a680203b55ebf018584815181106139e2576139e261595c565b602002602001015185604051613a169291906fffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a36001016136b2565b50909695505050505050565b60025460009073ffffffffffffffffffffffffffffffffffffffff1680613ab5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f73796e63207a65726f00000000000000000000000000000000000000000000006044820152606401611043565b825173ffffffffffffffffffffffffffffffffffffffff821631925060005b846020015151811015613b9b578173ffffffffffffffffffffffffffffffffffffffff1663ddd5e1b286602001518381518110613b1357613b1361595c565b6020026020010151856040518363ffffffff1660e01b8152600401613b5d92919060ff92909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015613b7757600080fd5b505af1158015613b8b573d6000803e3d6000fd5b505060019092019150613ad49050565b506135e88373ffffffffffffffffffffffffffffffffffffffff841631615a71565b600080613bca8584614a0b565b613bd48585613c53565b9050808511613c3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b613c498186615a71565b9150935093915050565b6040810151815161271063ffffffff90921684029190910490811015613c77575080515b81602001518111156119d9575060200151919050565b613c95610c4f565b7fd25b6a8963021505df4bb1195b7322076e3e1e78a7b02566befa7b6e9c99e8e580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25833613353565b600081471015613d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6661696c2073656e642076616c756500000000000000000000000000000000006044820152606401611043565b60405173ffffffffffffffffffffffffffffffffffffffff8416908390600081818185875af1925050503d8060008114613dc8576040519150601f19603f3d011682016040523d82523d6000602084013e613dcd565b606091505b505080915050806119d9578273ffffffffffffffffffffffffffffffffffffffff167f7a8da3fbf14e43fbfd79d8ce7ab913a13000dbbd248e9442988476e9e4b94cd883604051613e2091815260200190565b60405180910390a26000805462010000900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114613e9f576040519150601f19603f3d011682016040523d82523d6000602084013e613ea4565b606091505b5050905080613f0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6661696c20616d6f756e742063617463680000000000000000000000000000006044820152606401611043565b5092915050565b6040805173ffffffffffffffffffffffffffffffffffffffff831660208201527fd4504e868494e8a2d3346e969ceecbe7706b48fa405166a42593e57599e9067b918101919091526000906119d9906060016040516020818303038152906040528051906020012090565b6060613fa68383604051806060016040528060278152602001615c7160279139614ae4565b9392505050565b6000613fc183602001518560200151614a0b565b811561407857613fd983602001518560000151613c53565b905080836020015111614048576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f66656520616d6f756e74000000000000000000000000000000000000000000006044820152606401611043565b60208301805182900390526001546140769073ffffffffffffffffffffffffffffffffffffffff1682613d06565b505b60208301516040850151805161408f908390615b99565b6fffffffffffffffffffffffffffffffff1690525060408401516140e49080516020909101516fffffffffffffffffffffffffffffffff90811670010000000000000000000000000000000002911617600d55565b60006140ee6146a0565b9050836000015173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f87c8e141595387353b9f5800de2510b7678d07b38c7e01c29ab619d7938e6396866020015185604051614154929190918252602082015260400190565b60405180910390a361416984602001516144b9565b5050505050565b60008181526010602052604090205473ffffffffffffffffffffffffffffffffffffffff16806141fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f7769746864726177616c49642066696c746572000000000000000000000000006044820152606401611043565b600082815260106020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556004805482517f83453945000000000000000000000000000000000000000000000000000000008152925173ffffffffffffffffffffffffffffffffffffffff909116949385936383453945938181019391829003018187875af115801561429f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142c3919061599b565b73ffffffffffffffffffffffffffffffffffffffff166399a904b5856040518263ffffffff1660e01b81526004016142fd91815260200190565b60e060405180830381865afa15801561431a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061433e91906159b8565b606001516040517f0ad58d2f0000000000000000000000000000000000000000000000000000000081526004810187905260248101869052306044820152909150479073ffffffffffffffffffffffffffffffffffffffff841690630ad58d2f90606401600060405180830381600087803b1580156143bc57600080fd5b505af11580156143d0573d6000803e3d6000fd5b505050508181476143e19190615a71565b14614448576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f776974686472617720616d6f756e7400000000000000000000000000000000006044820152606401611043565b6144528483613d06565b5084868573ffffffffffffffffffffffffffffffffffffffff167f56938cd8bd3b7e9e03d3414d2307365bc79aa14190fc2b22e7119ad2ba26c48160405160405180910390a4505050505050565b6060806144ad8484614b69565b915091505b9250929050565b6040805180820182526004805473ffffffffffffffffffffffffffffffffffffffff1682526005805484516020828102820181019096528181526000958086019391929083018282801561454a57602002820191906000526020600020906000905b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161451b5790505b505050919092525050815191925060009050806145678486614b69565b9150915060005b8251811015614698578373ffffffffffffffffffffffffffffffffffffffff16636366ebe38383815181106145a5576145a561595c565b60200260200101516fffffffffffffffffffffffffffffffff168584815181106145d1576145d161595c565b60200260200101518585815181106145eb576145eb61595c565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815260ff90921660048301526fffffffffffffffffffffffffffffffff166024820152306044820152600060648201819052608482015260a4016000604051808303818588803b15801561467357600080fd5b505af1158015614687573d6000803e3d6000fd5b50506001909301925061456e915050565b505050505050565b600e805460009167ffffffffffffffff90911690826146be83615beb565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905090565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec57600061471083613f16565b805490915082151560ff909116151503614756576040517fa7b6d12000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80548215157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009091161790555050565b61478e611151565b610c8e576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b73ffffffffffffffffffffffffffffffffffffffff8216156128ec5773ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b602052604090205481151560ff9091161515036148e4576040517fd4be6f0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682158015919091179091556149d3577ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b80546001810182556000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555050565b6128ec7ff237d6838e11271a506165432935f4649c236dd23fbdf5c8717e2482cb88b88b83614c51565b611325610b3584848461270d565b8051821015614a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d696e696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b81816020015110156128ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f6d6178696d756d000000000000000000000000000000000000000000000000006044820152606401611043565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051614b0e9190615c12565b600060405180830381855af49150503d8060008114614b49576040519150601f19603f3d011682016040523d82523d6000602084013e614b4e565b606091505b5091509150614b5f86838387614db3565b9695505050505050565b606080836020015151600114614bdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f64656661756c74206e63704964000000000000000000000000000000000000006044820152606401611043565b60208401516040805160018082528183019092529193508160200160208202803683370190505090508281600081518110614c1857614c1861595c565b60200260200101906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff16815250509250929050565b815460005b818110156114d457838181548110614c7057614c7061595c565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff90811690841603614dab5783614ca8600184615a71565b81548110614cb857614cb861595c565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848281548110614cf557614cf561595c565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083805480614d4d57614d4d615c2e565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550505050565b600101614c56565b60608315614e49578251600003614e425773ffffffffffffffffffffffffffffffffffffffff85163b614e42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611043565b50816135e8565b6135e88383815115614e5e5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110439190615c5d565b82805482825590600052602060002090601f01602090048101928215614f285791602002820160005b83821115614ef957835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614ebb565b8015614f265782816101000a81549060ff0219169055600101602081600001049283019260010302614ef9565b505b50614f34929150614f38565b5090565b5b80821115614f345760008155600101614f39565b73ffffffffffffffffffffffffffffffffffffffff81168114610ca357600080fd5b600060208284031215614f8157600080fd5b8135613fa681614f4d565b803567ffffffffffffffff81168114614fa457600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715614ffb57614ffb614fa9565b60405290565b6040805190810167ffffffffffffffff81118282101715614ffb57614ffb614fa9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561506b5761506b614fa9565b604052919050565b600067ffffffffffffffff82111561508d5761508d614fa9565b5060051b60200190565b803560ff81168114614fa457600080fd5b600082601f8301126150b957600080fd5b813560206150ce6150c983615073565b615024565b828152606092830285018201928282019190878511156150ed57600080fd5b8387015b858110156130325781818a0312156151095760008081fd5b615111614fd8565b61511a82615097565b815281860135868201526040808301359082015284529284019281016150f1565b6000806000838503608081121561515157600080fd5b61515a85614f8c565b935060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08201121561518c57600080fd5b50615195615001565b60208501356151a381614f4d565b8152604085013560208201529150606084013567ffffffffffffffff8111156151cb57600080fd5b6151d7868287016150a8565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b81811015613a2657835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016151fd565b60006020828403121561524157600080fd5b5035919050565b803563ffffffff81168114614fa457600080fd5b60006060828403121561526e57600080fd5b615276614fd8565b823581526020830135602082015261529060408401615248565b60408201529392505050565b815163ffffffff16815260208083015173ffffffffffffffffffffffffffffffffffffffff169082015260408083015167ffffffffffffffff1690820152606081016119d9565b6000604082840312156152f557600080fd5b6152fd615001565b9050813561530a81614f4d565b815260208281013567ffffffffffffffff81111561532757600080fd5b8301601f8101851361533857600080fd5b80356153466150c982615073565b81815260059190911b8201830190838101908783111561536557600080fd5b928401925b8284101561538a5761537b84615097565b8252928401929084019061536a565b8085870152505050505092915050565b600080604083850312156153ad57600080fd5b82356153b881614f4d565b9150602083013567ffffffffffffffff8111156153d457600080fd5b6153e0858286016152e3565b9150509250929050565b6000602082840312156153fc57600080fd5b813567ffffffffffffffff81111561541357600080fd5b6135e8848285016152e3565b80356fffffffffffffffffffffffffffffffff81168114614fa457600080fd5b60006080828403121561545157600080fd5b6040516080810181811067ffffffffffffffff8211171561547457615474614fa9565b806040525082358152602083013560208201526154936040840161541f565b60408201526154a46060840161541f565b60608201529392505050565b600080600080606085870312156154c657600080fd5b84356154d181614f4d565b935060208501359250604085013567ffffffffffffffff808211156154f557600080fd5b818701915087601f83011261550957600080fd5b81358181111561551857600080fd5b88602082850101111561552a57600080fd5b95989497505060200194505050565b60005b8381101561555457818101518382015260200161553c565b50506000910152565b60008151808452615575816020860160208601615539565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b82151581526040602082015260006135e8604083018461555d565b6020808252825182820181905260009190848201906040850190845b81811015613a26578351835292840192918401916001016155de565b6000806040838503121561560d57600080fd5b50508035926020909101359150565b6000806020838503121561562f57600080fd5b823567ffffffffffffffff8082111561564757600080fd5b818501915085601f83011261565b57600080fd5b81358181111561566a57600080fd5b8660208260051b850101111561567f57600080fd5b60209290920196919550909350505050565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015615706577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526156f485835161555d565b945092850192908501906001016156ba565b5092979650505050505050565b60006060828403121561572557600080fd5b61572d614fd8565b61573683615248565b8152602083013561574681614f4d565b602082015261529060408401614f8c565b6020808252825173ffffffffffffffffffffffffffffffffffffffff16828201528281015160408084015280516060840181905260009291820190839060808601905b808310156157bd57835160ff16825292840192600192909201919084019061579a565b509695505050505050565b600060208083850312156157db57600080fd5b823567ffffffffffffffff8111156157f257600080fd5b8301601f8101851361580357600080fd5b80356158116150c982615073565b81815260059190911b8201830190838101908783111561583057600080fd5b928401925b8284101561585757833561584881614f4d565b82529284019290840190615835565b979650505050505050565b60008060006060848603121561587757600080fd5b61588084614f8c565b925060208401359150604084013567ffffffffffffffff8111156151cb57600080fd5b600481106158da577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260c0810161592d60608301856158a3565b73ffffffffffffffffffffffffffffffffffffffff8351166080830152602083015160a0830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183823760009101908152919050565b6000602082840312156159ad57600080fd5b8151613fa681614f4d565b600060e082840312156159ca57600080fd5b60405160e0810181811067ffffffffffffffff821117156159ed576159ed614fa9565b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c0830151615a3681614f4d565b60c08201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156119d9576119d9615a42565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615ab957600080fd5b83018035915067ffffffffffffffff821115615ad457600080fd5b6020019150368190038213156144b257600080fd5b828482376000838201600081528351615b06818360208801615539565b0195945050505050565b808201808211156119d9576119d9615a42565b835163ffffffff16815260208085015173ffffffffffffffffffffffffffffffffffffffff169082015260408085015167ffffffffffffffff169082015260a08101615b7260608301856158a3565b826080830152949350505050565b600060208284031215615b9257600080fd5b5051919050565b6fffffffffffffffffffffffffffffffff818116838216019080821115613f0f57613f0f615a42565b6fffffffffffffffffffffffffffffffff828116828216039080821115613f0f57613f0f615a42565b600067ffffffffffffffff808316818103615c0857615c08615a42565b6001019392505050565b60008251615c24818460208701615539565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b602081526000613fa6602083018461555d56fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212209c771ad8a1e0b048b08be8f0d36d466b7655b6a8b9fede21ff34f40f4ef3f6da64736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007d76ae60dcc2fdb57d3924024e2ad940b76ef81f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000006af09e1a3c886dd8560bf4cabd65db16ea2724d8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000029
-----Decoded View---------------
Arg [0] : owner (address): 0x7D76Ae60dcc2FdB57d3924024E2Ad940B76Ef81f
Arg [1] : _stakingInfo (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000007d76ae60dcc2fdb57d3924024e2ad940b76ef81f
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000006af09e1a3c886dd8560bf4cabd65db16ea2724d8
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000029
Deployed Bytecode Sourcemap
459:9230:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1949:19:2;:17;:19::i;:::-;459:9230:5;;;;;319:39:4;;;;;;;;;;;;353:5;319:39;;;;;188:10:31;176:23;;;158:42;;146:2;131:18;319:39:4;;;;;;;;2041:107:1;;;;;;;;;;-1:-1:-1;2041:107:1;;;;;:::i;:::-;;:::i;620:33:4:-;;;;;;;;;;-1:-1:-1;620:33:4;;;;;;;;;;;796:18:31;784:31;;;766:50;;754:2;739:18;620:33:4;622:200:31;3419:583:4;;;;;;;;;;-1:-1:-1;3419:583:4;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1992:124:3:-;;;;;;;;;;-1:-1:-1;1992:124:3;;;;;:::i;:::-;;:::i;:::-;;;5408:42:31;5396:55;;;5378:74;;5366:2;5351:18;1992:124:3;5232:226:31;1084:115:4;;;;;;;;;;-1:-1:-1;1084:115:4;;;;;:::i;:::-;;:::i;2966:97::-;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;3043:17:4;;;;;;;3050:10;3043:17;;;;;;;;;;;;;;;;;;;;2966:97;;5716:41:31;;;5799:24;;5795:33;;;5773:20;;;5766:63;;;;5636:18;2966:97:4;5463:372:31;2443:70:1;;;;;;;;;;;;;:::i;2122:117:3:-;;;;;;;;;;-1:-1:-1;1839:66:3;2194:38;2122:117;;;5986:25:31;;;5974:2;5959:18;2122:117:3;5840:177:31;1827:238:4;;;;;;;;;;-1:-1:-1;1827:238:4;;;;;:::i;:::-;;:::i;968:111::-;;;;;;;;;;-1:-1:-1;968:111:4;;;;;:::i;:::-;;:::i;2507:121::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;2604:21:4;;;;;;;;2611:14;2604:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;2507:121;;;;;;;;:::i;2325:86:2:-;;;;;;;;;;;;;:::i;:::-;;;7370:14:31;;7363:22;7345:41;;7333:2;7318:18;2325:86:2;7205:187:31;712:249:5;;;;;;;;;;-1:-1:-1;712:249:5;;;;;:::i;:::-;;:::i;2739:95:4:-;;;;;;;;;;;;;:::i;:::-;;;;9157:13:31;;9139:32;;9227:4;9215:17;;;9209:24;9187:20;;;9180:54;9282:17;;;9276:24;9302:10;9272:41;9250:20;;;9243:71;9127:2;9112:18;2739:95:4;8939:381:31;1556:265:4;;;;;;;;;;-1:-1:-1;1556:265:4;;;;;:::i;:::-;;:::i;659:76::-;;;;;;;;;;-1:-1:-1;659:76:4;;;;;:::i;:::-;;;;;;;;;;;;;;;;2071:305;;;;;;;;;;-1:-1:-1;2071:305:4;;;;;:::i;:::-;;:::i;2543:124:3:-;;;;;;;;;;-1:-1:-1;2543:124:3;;;;;:::i;:::-;;:::i;831:36:4:-;;;;;;;;;;-1:-1:-1;831:36:4;;;;;;;;364:25;;;;;;;;;;-1:-1:-1;364:25:4;;;;;;;;1689:229:1;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;1354:589:5:-;;;;;;;;;;-1:-1:-1;1354:589:5;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1831:101:0:-;;;;;;;;;;;;;:::i;3069:213:4:-;;;;;;;;;;-1:-1:-1;3069:213:4;;;;;:::i;:::-;;:::i;:::-;;;;13044:25:31;;;13100:2;13085:18;;13078:34;;;;13017:18;3069:213:4;12870:248:31;3287:126:4;;;;;;;;;;-1:-1:-1;3287:126:4;;;;;:::i;:::-;;:::i;2400:137:3:-;;;;;;;;;;-1:-1:-1;2400:137:3;;;;;:::i;:::-;2487:43;;2464:4;2487:43;;;1839:66;2487:43;;;;;;;;;2400:137;2839:122:4;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2933:25:4;;;;;;;;2940:18;2933:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2839:122;;;;;13360:13:31;;13342:32;;13430:4;13418:17;;;13412:24;13390:20;;;13383:54;13472:17;;;13466:24;13509:34;13581:21;;;13559:20;;;13552:51;;;;13663:4;13651:17;;;13645:24;13641:33;;;13619:20;;;13612:63;;;;13329:3;13314:19;2839:122:4;13123:558:31;2371:66:1;;;;;;;;;;;;;:::i;1208:85:0:-;;;;;;;;;;-1:-1:-1;1254:7:0;1280:6;;;;;;1208:85;;3856:829:5;;;;;;;;;;-1:-1:-1;3856:829:5;;;;;:::i;:::-;;:::i;2245:149:3:-;;;;;;;;;;;;;:::i;2268:97:1:-;;;;;;;;;;;;;:::i;741:83:4:-;;;;;;;;;;-1:-1:-1;741:83:4;;;;;:::i;:::-;;;;;;;;;;;;;;;;1924:111:1;;;;;;;;;;-1:-1:-1;1924:111:1;;;;;:::i;:::-;;:::i;1235:484:21:-;;;;;;;;;;-1:-1:-1;1235:484:21;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1205:346:4:-;;;;;;;;;;-1:-1:-1;1205:346:4;;;;;:::i;:::-;;:::i;2633:101::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;1030:318:5:-;;;;;;:::i;:::-;;:::i;2103:95::-;;;;;;;;;;;;;:::i;2154:108:1:-;;;;;;;;;;-1:-1:-1;2154:108:1;;;;;:::i;:::-;;:::i;2804:725:3:-;;;;;;;;;;-1:-1:-1;2804:725:3;;;;;:::i;:::-;;:::i;2673:125::-;;;;;;;;;;-1:-1:-1;2673:125:3;;;;;:::i;:::-;;:::i;395:26:4:-;;;;;;;;;;-1:-1:-1;395:26:4;;;;;;;;2382:119;;;;;;;;;;-1:-1:-1;2382:119:4;;;;;:::i;:::-;;:::i;4222:583::-;;;;;;;;;;-1:-1:-1;4222:583:4;;;;;:::i;:::-;;:::i;1949:148:5:-;;;;;;;;;;-1:-1:-1;1949:148:5;;;;;:::i;:::-;;:::i;5025:551:4:-;;;;;;;;;;-1:-1:-1;5025:551:4;;;;;:::i;:::-;;:::i;2081:198:0:-;;;;;;;;;;-1:-1:-1;2081:198:0;;;;;:::i;:::-;;:::i;2759:1091:5:-;;;;;;;;;;-1:-1:-1;2759:1091:5;;;;;:::i;:::-;;:::i;2204:549::-;;;:::i;2479:104:2:-;2544:8;:6;:8::i;:::-;2540:36;;;2561:15;;;;;;;;;;;;;;2540:36;2479:104::o;2041:107:1:-;1101:13:0;:11;:13::i;:::-;2104:37:1::1;2131:1;2135:5;2104:18;:37::i;:::-;2041:107:::0;:::o;3419:583:4:-;3599:52;;;3563:24;3599:52;;;;;3637:14;3599:52;;;;;;;;;;;;;;;;;;;;3661:23;;3599:52;;;3661:23;3724:61;;3563:24;;-1:-1:-1;;3724:61:4;;3599:52;;;;3773:11;;3724:61;;:::i;:::-;;;;;;;;;;;;;3714:72;;;;;;3695:91;;3821:4;:11;3807:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3807:26:4;;3797:36;;3848:9;3844:152;3861:4;:11;3859:1;:13;3844:152;;;3902:52;3912:8;3922:4;3927:1;3922:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3933:4;3938:1;3933:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3944:4;3949:1;3944:7;;;;;;;;:::i;:::-;;;;;;;:9;;;3902:52;;;;;;;;;;;;;;;;;19669:25:31;;;19742:4;19730:17;;;;19725:2;19710:18;;19703:45;19779:2;19764:18;;19757:34;19822:2;19807:18;;19800:34;19656:3;19641:19;;19442:398;3902:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3889:7;3897:1;3889:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;3980:3;;3844:152;;;;3589:413;;3419:583;;;;;:::o;1992:124:3:-;2045:7;1839:66;2103:5;2071:38;;;;;;;;:::i;:::-;;;;;;;;;;;;;;1992:124;-1:-1:-1;;1992:124:3:o;1084:115:4:-;1101:13:0;:11;:13::i;:::-;1166:11:4::1;:26:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;1084:115::o;2443:70:1:-;1313:22;734:10:19;1924:111:1;:::i;1313:22::-;:49;;;-1:-1:-1;1254:7:0;1280:6;;;;;;1339:23:1;;734:10:19;1339:23:1;;;1313:49;1307:76;;1372:11;;;;;;;;;;;;;;1307:76;2496:10:::1;:8;:10::i;1827:238:4:-:0;1101:13:0;:11;:13::i;:::-;353:5:4::1;1922:27;;:10;:15;;;:27;;;;1914:48;;;::::0;::::1;::::0;;20047:2:31;1914:48:4::1;::::0;::::1;20029:21:31::0;20086:1;20066:18;;;20059:29;20124:10;20104:18;;;20097:38;20152:18;;1914:48:4::1;;;;;;;;;1998:14;::::0;::::1;::::0;1980;;:32:::1;;1972:54;;;::::0;::::1;::::0;;20383:2:31;1972:54:4::1;::::0;::::1;20365:21:31::0;20422:1;20402:18;;;20395:29;20460:11;20440:18;;;20433:39;20489:18;;1972:54:4::1;20181:332:31::0;1972:54:4::1;2036:22:::0;;:9:::1;:22:::0;::::1;::::0;::::1;::::0;;;::::1;;::::0;;;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;1827:238::o;968:111::-;1101:13:0;:11;:13::i;:::-;1048:10:4::1;:24:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;968:111::o;2325:86:2:-;2372:4;2395:9;846:66;983:47;;;;919:118;2395:9;2388:16;;2325:86;:::o;712:249:5:-;3283:19:10;3306:13;;;;;;3305:14;;3351:34;;;;-1:-1:-1;3369:12:10;;3384:1;3369:12;;;;:16;3351:34;3350:108;;;-1:-1:-1;3430:4:10;1713:19:18;:23;;;3391:66:10;;-1:-1:-1;3440:12:10;;;;;:17;3391:66;3329:201;;;;;;;20720:2:31;3329:201:10;;;20702:21:31;20759:2;20739:18;;;20732:30;20798:34;20778:18;;;20771:62;20869:16;20849:18;;;20842:44;20903:19;;3329:201:10;20518:410:31;3329:201:10;3540:12;:16;;;;3555:1;3540:16;;;3566:65;;;;3600:13;:20;;;;;;;;3566:65;851:30:5::1;870:10;851:18;:30::i;:::-;891:28;906:12;891:14;:28::i;:::-;929:25;948:5;929:18;:25::i;:::-;3655:14:10::0;3651:99;;;3701:5;3685:21;;;;;;3725:14;;-1:-1:-1;21085:36:31;;3725:14:10;;21073:2:31;21058:18;3725:14:10;;;;;;;3651:99;3273:483;712:249:5;;:::o;2739:95:4:-;2795:16;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;2795:16:4;-1:-1:-1;2815:16:4;;;;;;;;2822:9;2815:16;;;;;;;;;;;;;;;;;;;;;2739:95::o;1556:265::-;1101:13:0;:11;:13::i;:::-;1657:27:4;;:41:::1;;1649:68;;;::::0;::::1;::::0;;21334:2:31;1649:68:4::1;::::0;::::1;21316:21:31::0;21373:2;21353:18;;;21346:30;21412:16;21392:18;;;21385:44;21446:18;;1649:68:4::1;21132:338:31::0;1649:68:4::1;1735:12;:19;;;:26;1765:1;1735:31;1727:50;;;::::0;::::1;::::0;;21677:2:31;1727:50:4::1;::::0;::::1;21659:21:31::0;21716:1;21696:18;;;21689:29;21754:8;21734:18;;;21727:36;21780:18;;1727:50:4::1;21475:329:31::0;1727:50:4::1;1788:26:::0;;:11:::1;:26:::0;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;:11;:26:::1;::::0;;;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;1556:265:4:o;2071:305::-;1101:13:0;:11;:13::i;:::-;2193:23:4;;2185:50:::1;;;::::0;::::1;::::0;;22011:2:31;2185:50:4::1;::::0;::::1;21993:21:31::0;22050:2;22030:18;;;22023:30;22089:12;22069:18;;;22062:40;22119:18;;2185:50:4::1;21809:334:31::0;2185:50:4::1;2279:23;::::0;::::1;::::0;2253;;:49:::1;2245:74;;;::::0;::::1;::::0;;22350:2:31;2245:74:4::1;::::0;::::1;22332:21:31::0;22389:2;22369:18;;;22362:30;22428:14;22408:18;;;22401:42;22460:18;;2245:74:4::1;22148:336:31::0;2245:74:4::1;2329:40:::0;;:18:::1;:40:::0;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;;2071:305::o;2543:124:3:-;1313:22:1;734:10:19;1924:111:1;:::i;1313:22::-;:49;;;-1:-1:-1;1254:7:0;1280:6;;;;;;1339:23:1;;734:10:19;1339:23:1;;;1313:49;1307:76;;1372:11;;;;;;;;;;;;;;1307:76;2621:39:3::1;2649:1;2653:6;2621:19;:39::i;1689:229:1:-:0;1826:12;1840:23;1101:13:0;:11;:13::i;:::-;1882:2:1::1;:7;;1898:5;1906:4;;1882:29;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1875:36;;;;1689:229:::0;;;;;;;:::o;1354:589:5:-;1516:30;1949:19:2;:17;:19::i;:::-;1567:24:5::1;::::0;::::1;;::::0;;;:14:::1;:24;::::0;;;;;::::1;;1566:25;1558:47;;;::::0;::::1;::::0;;22967:2:31;1558:47:5::1;::::0;::::1;22949:21:31::0;23006:1;22986:18;;;22979:29;23044:11;23024:18;;;23017:39;23073:18;;1558:47:5::1;22765:332:31::0;1558:47:5::1;1615:24;::::0;::::1;;::::0;;;:14:::1;:24;::::0;;;;:31;;;::::1;1642:4;1615:31;::::0;;1690:20:::1;:18;:20::i;:::-;1657:53;;1743:58;1765:8;1775;1785:9;1796:4;1743:21;:58::i;:::-;1721:19;::::0;::::1;:80:::0;1827:26:::1;1843:9:::0;1827:15:::1;:26::i;:::-;1811:42;;1864:37;1881:8;:19;;;6203:23:4::0;;;;;;;;;;;;;;;;:10;:23;6129:104;1864:37:5::1;1911:25;::::0;;;;::::1;::::0;;1924:11:::1;1911:25:::0;;::::1;;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;::::1;::::0;;;::::1;::::0;;;;;::::1;::::0;;;::::1;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;;::::1;::::0;::::1;;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;;;;;;;;;;;;;::::0;::::1;:12;:25::i;:::-;;1548:395;1354:589:::0;;;;;:::o;1831:101:0:-;1101:13;:11;:13::i;:::-;1895:30:::1;1922:1;1895:18;:30::i;3069:213:4:-:0;3211:64;;;;;;;;;3245:9;3211:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;3256:18;3211:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3151:22;;;;3211:64;;3237:6;;3211:64;:25;:64::i;:::-;3204:71;;;;3069:213;;;:::o;3287:126::-;3379:27;;;;;;;;3396:9;3379:27;;;;;;;;;;;;;;;;;;;;3343:17;;3379:27;;3388:6;;3379:8;:27::i;:::-;3372:34;3287:126;-1:-1:-1;;3287:126:4:o;2371:66:1:-;1313:22;734:10:19;1924:111:1;:::i;1313:22::-;:49;;;-1:-1:-1;1254:7:0;1280:6;;;;;;1339:23:1;;734:10:19;1339:23:1;;;1313:49;1307:76;;1372:11;;;;;;;;;;;;;;1307:76;2422:8:::1;:6;:8::i;3856:829:5:-:0;3955:32;;;;:18;:32;;;;;;:49;:32;3999:4;3955:49;3947:81;;;;;;;23304:2:31;3947:81:5;;;23286:21:31;23343:2;23323:18;;;23316:30;23382:21;23362:18;;;23355:49;23421:18;;3947:81:5;23102:343:31;3947:81:5;4045:32;;;;:18;:32;;;;;;;;4038:39;;;;;;;4109:10;4164:11;:26;;4218:23;;;;;;;4038:39;4109:10;;;;4164:26;;;;;4045:32;;4164:26;;4218:21;;:23;;;;4045:32;4218:23;;;;;4045:32;4164:26;4218:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;;4267:12;4218:62;;;;;;;;;;;;;5986:25:31;;5974:2;5959:18;;5840:177;4218:62:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:69;;;4352:109;;;;;;;;24837:25:31;;;24878:18;;;24871:34;;;4444:4:5;24921:18:31;;;24914:83;4218:69:5;;-1:-1:-1;4321:21:5;;4352:16;;;;;;24810:18:31;;4352:109:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4520:6;4503:13;4479:21;:37;;;;:::i;:::-;:47;4471:75;;;;;;;25532:2:31;4471:75:5;;;25514:21:31;25571:2;25551:18;;;25544:30;25610:17;25590:18;;;25583:45;25645:18;;4471:75:5;25330:339:31;4471:75:5;4603:12;4596:5;4583:11;4561:55;;;;;;;;;;;;4626:52;4657:11;4671:6;4626:22;:52::i;:::-;;3937:748;;;;3856:829;;:::o;2245:149:3:-;2288:16;1839:66;2349:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2245:149;:::o;2268:97:1:-;2314:44;734:10:19;2355:1:1;2314:18;:44::i;1924:111::-;1978:4;2001:21;2016:5;2001:14;:21::i;:::-;:27;;;;1924:111;-1:-1:-1;;1924:111:1:o;1235:484:21:-;1401:12;;;1337:20;1401:12;;;;;;;;1303:22;;1512:4;1500:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1490:34;;1539:9;1534:155;1554:15;;;1534:155;;;1603:75;1640:4;1660;;1665:1;1660:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1669;1647:30;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1603:28;:75::i;:::-;1590:7;1598:1;1590:10;;;;;;;;:::i;:::-;;;;;;;;;;:88;1571:3;;1534:155;;;;1698:14;1235:484;;;;:::o;1205:346:4:-;1101:13:0;:11;:13::i;:::-;1319:22:4::1;::::0;::::1;::::0;:36:::1;;1311:63;;;::::0;::::1;::::0;;27242:2:31;1311:63:4::1;::::0;::::1;27224:21:31::0;27281:2;27261:18;;;27254:30;27320:16;27300:18;;;27293:44;27354:18;;1311:63:4::1;27040:338:31::0;1311:63:4::1;1392:23:::0;;:28:::1;;:23;:28:::0;1384:56:::1;;;::::0;::::1;::::0;;27585:2:31;1384:56:4::1;::::0;::::1;27567:21:31::0;27624:2;27604:18;;;27597:30;27663:17;27643:18;;;27636:45;27698:18;;1384:56:4::1;27383:339:31::0;1384:56:4::1;1458:21;::::0;::::1;::::0;:26:::1;;::::0;1450:51:::1;;;::::0;::::1;::::0;;27929:2:31;1450:51:4::1;::::0;::::1;27911:21:31::0;27968:2;27948:18;;;27941:30;28007:14;27987:18;;;27980:42;28039:18;;1450:51:4::1;27727:336:31::0;1450:51:4::1;1512:32:::0;;:14:::1;:32:::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;;::::1;;::::0;;1205:346::o;2633:101::-;-1:-1:-1;;;;;;;;;;;;;;;;;2713:18:4;;;;;;;;2720:11;2713:18;;;;;;;;;;;;;;;;;;;;;;;;;;;2720:11;;2713:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2633:101;:::o;1030:318:5:-;1949:19:2;:17;:19::i;:::-;1116:21:5::1;::::0;::::1;1113:46;;-1:-1:-1::0;1149:10:5::1;1113:46;1170:30;1203:20;:18;:20::i;:::-;1170:53;;1233:73;1256:8;1266:33;;;;;;;;1280:7;1266:33;;;;;;1289:9;1266:33;;::::0;1301:4:::1;1233:22;:73::i;:::-;1316:25;::::0;;;;::::1;::::0;;1329:11:::1;1316:25:::0;;::::1;;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;::::1;::::0;;;::::1;::::0;;;;;::::1;::::0;;;::::1;;;;::::0;;;::::1;::::0;;;;;;::::1;;::::0;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;;;;;;;;;;;;::::0;::::1;:12;:25::i;2103:95::-:0;1949:19:2;:17;:19::i;:::-;2166:25:5::1;::::0;;;;::::1;::::0;;2179:11:::1;2166:25:::0;;::::1;;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;::::1;::::0;;;::::1;::::0;;;;;::::1;::::0;;;::::1;;;;::::0;;;::::1;::::0;;;;;;::::1;;::::0;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;;;;;;;;;;;;::::0;::::1;:12;:25::i;2154:108:1:-:0;1101:13:0;:11;:13::i;:::-;2218:37:1::1;2237:5;2252:1;2218:18;:37::i;2804:725:3:-:0;2888:15;;3004:1;1839:66;2962:38;2961:49;;2962:43;3009:1;2961:49;:::i;:::-;2954:3;:56;;2946:75;;;;;;;28400:2:31;2946:75:3;;;28382:21:31;28439:1;28419:18;;;28412:29;28477:8;28457:18;;;28450:36;28503:18;;2946:75:3;28198:329:31;2946:75:3;3040:1;3034:3;:7;3031:261;;;3057:13;3073:5;3077:1;3073:3;:5;:::i;:::-;3057:21;;3096:9;3092:190;3111:5;3107:1;:9;3092:190;;;3200:8;3209:3;:1;3211;3209:3;:::i;:::-;3200:13;;;;;;;;:::i;:::-;;;;;;;3186:27;;:8;3195:1;3186:11;;;;;;;;:::i;:::-;;;;;;;:27;;;3178:55;;;;;;;28734:2:31;3178:55:3;;;28716:21:31;28773:2;28753:18;;;28746:30;28812:17;28792:18;;;28785:45;28847:18;;3178:55:3;28532:339:31;3178:55:3;3262:3;;3092:190;;;;3043:249;3031:261;1839:66;3302:42;3392:131;3411:3;3407:1;:7;3392:131;;;3439:9;:24;3450:8;3459:1;3450:11;;;;;;;;:::i;:::-;;;;;;;;;;;;3439:24;;;;;;;;;;;;-1:-1:-1;3439:24:3;;;;3431:51;;;;;;;29078:2:31;3431:51:3;;;29060:21:31;29117:2;29097:18;;;29090:30;29156:16;29136:18;;;29129:44;29190:18;;3431:51:3;28876:338:31;3431:51:3;3507:3;;3392:131;;2673:125;1313:22:1;734:10:19;1924:111:1;:::i;1313:22::-;:49;;;-1:-1:-1;1254:7:0;1280:6;;;;;;1339:23:1;;734:10:19;1339:23:1;;;1313:49;1307:76;;1372:11;;;;;;;;;;;;;;1307:76;2752:39:3::1;2772:6;2788:1;2752:19;:39::i;2382:119:4:-:0;1101:13:0;:11;:13::i;:::-;2466:12:4::1;:28:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;2382:119::o;4222:583::-;4402:52;;;4366:24;4402:52;;;;;4440:14;4402:52;;;;;;;;;;;;;;;;;;;;4464:23;;4402:52;;;4464:23;4527:61;;4366:24;;-1:-1:-1;;4527:61:4;;4402:52;;4549:25;;4576:11;;4527:61;;:::i;:::-;;;;;;;;;;;;;4517:72;;;;;;4498:91;;4624:4;:11;4610:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4610:26:4;;4600:36;;4651:9;4647:152;4664:4;:11;4662:1;:13;4647:152;;;4705:52;4715:8;4725:4;4730:1;4725:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4736:4;4741:1;4736:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4747:4;4752:1;4747:7;;;;;;;;:::i;:::-;;;;;;;:9;;;4705:52;;;;;;;;;;;;;;;;;19669:25:31;;;19742:4;19730:17;;;;19725:2;19710:18;;19703:45;19779:2;19764:18;;19757:34;19822:2;19807:18;;19800:34;19656:3;19641:19;;19442:398;4705:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4692:7;4700:1;4692:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;4783:3;;4647:152;;1949:148:5;:19:2;:17;:19::i;:::-;2053:37:5::1;2070:5;2077:12;2053:16;:37::i;:::-;1949:148:::0;;:::o;5025:551:4:-;5183:52;;;5147:24;5183:52;;;;;5221:14;5183:52;;;;;;;;;;;;;;;;;;;;;5245:23;;5183:52;;;5245:23;5308:52;;5147:24;;-1:-1:-1;;5308:52:4;;5183;;5221:14;;5353:6;;5308:52;;:::i;:::-;;;;;;;;;;;;;5298:63;;;;;;5279:82;;5395:4;:11;5381:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5381:26:4;;5371:36;;5422:9;5418:152;5435:4;:11;5433:1;:13;5418:152;;;5476:52;5486:8;5496:4;5501:1;5496:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5507:4;5512:1;5507:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5518:4;5523:1;5518:7;;;;;;;;:::i;:::-;;;;;;;:9;;;5476:52;;;;;;;;;;;;;;;;;19669:25:31;;;19742:4;19730:17;;;;19725:2;19710:18;;19703:45;19779:2;19764:18;;19757:34;19822:2;19807:18;;19800:34;19656:3;19641:19;;19442:398;5476:52:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5463:7;5471:1;5463:10;;;;;;;;:::i;:::-;:65;;;;:10;;;;;;;;;;;:65;5554:3;;5418:152;;2081:198:0;1101:13;:11;:13::i;:::-;2169:22:::1;::::0;::::1;2161:73;;;::::0;::::1;::::0;;29894:2:31;2161:73:0::1;::::0;::::1;29876:21:31::0;29933:2;29913:18;;;29906:30;29972:34;29952:18;;;29945:62;30043:8;30023:18;;;30016:36;30069:19;;2161:73:0::1;29692:402:31::0;2161:73:0::1;2244:28;2263:8;2244:18;:28::i;2759:1091:5:-:0;2843:30;1313:22:1;734:10:19;1924:111:1;:::i;1313:22::-;:49;;;-1:-1:-1;1254:7:0;1280:6;;;;;;1339:23:1;;734:10:19;1339:23:1;;;1313:49;1307:76;;1372:11;;;;;;;;;;;;;;1307:76;2907:10:5::1;::::0;2928:45:::1;::::0;;;;::::1;::::0;;2962:11:::1;2928:45:::0;;2907:10:::1;2928:45:::0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;2907:10;;;::::1;::::0;2885:19:::1;::::0;2928:45;;::::1;::::0;;;;;::::1;::::0;;;::::1;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;;::::1;::::0;::::1;;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;;;;;;-1:-1:-1::0;;;2928:45:5;;;;-1:-1:-1;;3017:27:5;;2928:45;;-1:-1:-1;2983:19:5::1;::::0;-1:-1:-1;2983:19:5;3103:51:::1;2928:45:::0;3146:6;3103:20:::1;:51::i;:::-;3055:99;;;;3165:17;3197:9:::0;3193:609:::1;3210:6;:13;3208:1;:15;3193:609;;;3256:3;3260:1;3256:6;;;;;;;;:::i;:::-;;;;;;;3244:18;;;;3294:7;:23;;;3335:6;3342:1;3335:9;;;;;;;;:::i;:::-;;;;;;;3379:6;3386:1;3379:9;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;3294:278:::1;::::0;;::::1;::::0;;;;;;30416:4:31;30404:17;;;3294:278:5::1;::::0;::::1;30386:36:31::0;30458:17;;30438:18;;;30431:45;30492:18;;;30485:34;;;3476:4:5::1;30535:18:31::0;;;30528:83;3506:5:5::1;30627:19:31::0;;;30620:51;;;30687:19;;;30680:51;30358:19;;3294:278:5::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3277:3;3281:1;3277:6;;;;;;;;:::i;:::-;;;;;;:296;;;;;;;;;::::0;::::1;3634:1;3596:40;;:18;:26;3615:3;3619:1;3615:6;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;3596:26:::1;;::::0;;;::::1;::::0;;;;;;-1:-1:-1;3596:26:5;;::::1;;:40;3588:65;;;::::0;::::1;::::0;;31133:2:31;3588:65:5::1;::::0;::::1;31115:21:31::0;31172:2;31152:18;;;31145:30;31211:14;31191:18;;;31184:42;31243:18;;3588:65:5::1;30931:336:31::0;3588:65:5::1;3704:4;3667:18;:26;3686:3;3690:1;3686:6;;;;;;;;:::i;:::-;;;;;;;3667:26;;;;;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;3762:6;3769:1;3762:9;;;;;;;;:::i;:::-;;;;;;;3728:63;;3749:11;3728:63;;;3773:3;3777:1;3773:6;;;;;;;;:::i;:::-;;;;;;;3781:9;3728:63;;;;;;31476:34:31::0;31464:47;;;;31446:66;;31543:2;31528:18;;31521:34;31434:2;31419:18;;31272:289;3728:63:5::1;;;;;;;;3225:3;;3193:609;;;-1:-1:-1::0;3839:3:5;;2759:1091;-1:-1:-1;;;;;;;2759:1091:5:o;2204:549::-;1949:19:2;:17;:19::i;:::-;2270:30:5::1;2303:20;:18;:20::i;:::-;2356:11;::::0;2270:53;;-1:-1:-1;2356:11:5::1;;2386:10;:26:::0;::::1;2378:43;;;;;;;;;;;31768:2:31::0;31750:21;;;31807:1;31787:18;;;31780:29;31845:6;31840:2;31825:18;;31818:34;31884:2;31869:18;;31566:327;2378:43:5::1;2432:17;2439:9;2432:6;:17::i;:::-;2509:9;2460:8;:19;;;:37;;:59;;;;;;;:::i;:::-;;;::::0;;-1:-1:-1;2529:19:5::1;::::0;::::1;::::0;:42:::1;;:64:::0;;2583:9:::1;::::0;2529:42;:64:::1;::::0;2583:9;;2529:64:::1;:::i;:::-;;;::::0;;-1:-1:-1;2621:19:5::1;::::0;::::1;::::0;2604:37:::1;::::0;6203:23:4;;;;;;;;;;;;;;;;:10;:23;6129:104;2604:37:5::1;2652:18;2673:16;:14;:16::i;:::-;2652:37;;2722:12;2704:42;;2709:11;2704:42;;;2736:9;2704:42;;;;5986:25:31::0;;5974:2;5959:18;;5840:177;2704:42:5::1;;;;;;;;2260:493;;;2204:549::o:0;1366:130:0:-;1254:7;1280:6;1429:23;1280:6;;;;;734:10:19;1429:23:0;1421:68;;;;;;;32302:2:31;1421:68:0;;;32284:21:31;;;32321:18;;;32314:30;32380:34;32360:18;;;32353:62;32432:18;;1421:68:0;32100:356:31;3094:224:1;3179:33;3195:9;3206:5;3179:15;:33::i;:::-;3222:32;3238:9;3249:4;3222:15;:32::i;:::-;3301:9;3269:42;;3290:9;3269:42;;;;;;;;;;;;3094:224;;:::o;3141:119:2:-;2196:16;:14;:16::i;:::-;846:66;1092:54;;;;;;3231:22:::1;734:10:19::0;3240:12:2::1;3231:22;::::0;5408:42:31;5396:55;;;5378:74;;5366:2;5351:18;3231:22:2::1;;;;;;;3141:119::o:0;1450:233:1:-;1532:16;1280:6:0;;;;;;1572:18:1;1280:6:0;1572:8:1;:18::i;:::-;1568:64;;;1592:40;1611:8;1629:1;1592:18;:40::i;:::-;1642:34;1667:8;1642:24;:34::i;4225:227:3:-;4313:33;4328:10;4340:5;4313:14;:33::i;:::-;4356:32;4371:10;4383:4;4356:14;:32::i;:::-;4434:10;4403:42;;4422:10;4403:42;;;;;;;;;;;;4225:227;;:::o;5765:232:4:-;5818:30;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5818:30:4;5860:48;;;;;;;;5890:18;5860:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:27;;;:48;;;;5918:30;;;;;;;5939:9;5918:30;;;;;;;;;;;;;;;;;;;;5958:32;;;;;;;5980:10;5958:32;;;;;;;;;;;;;;;;;:19;;;:32;5860:8;5765:232::o;6155:462:5:-;-1:-1:-1;;;;;;;;;;;;;;;;;6369:49:5;6392:8;6402:9;6413:4;6369:22;:49::i;:::-;6478:16;;;;6429:19;;;;:66;;;;6478:16;;6429:66;:::i;:::-;;;;;-1:-1:-1;6538:17:5;;6557:16;;;;;6511:63;;5986:25:31;;;6511:63:5;;;;;;;;;;;5959:18:31;6511:63:5;;;;;;;-1:-1:-1;6591:19:5;;;;6155:462;;;;;;;:::o;6623:1091::-;6740:45;;;;;;;;6774:11;6740:45;;;;;;;;;;;;;;;;;;;;;;;;;6698:30;;6740:31;;:45;6774:11;6740:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6795:19;6829:12;:27;;;6795:62;;6868:21;6891:20;6915:61;6936:12;6958:9;:16;;;6915:20;:61::i;:::-;6867:109;;;;6987:17;7019:9;7015:612;7032:6;:13;7030:1;:15;7015:612;;;7078:3;7082:1;7078:6;;;;;;;;:::i;:::-;;;;;;;7066:18;;;;7115:7;:23;;;7156:6;7163:1;7156:9;;;;;;;;:::i;:::-;;;;;;;7200:6;7207:1;7200:9;;;;;;;;:::i;:::-;;;;;;;;;;;7115:278;;;;;;;;;;30416:4:31;30404:17;;;7115:278:5;;;30386:36:31;30458:17;;30438:18;;;30431:45;30492:18;;;30485:34;;;7297:4:5;30535:18:31;;;30528:83;7327:5:5;30627:19:31;;;30620:51;;;30687:19;;;30680:51;30358:19;;7115:278:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7098:3;7102:1;7098:6;;;;;;;;:::i;:::-;;;;;;:296;;;;;;;;;;;7455:1;7417:40;;:18;:26;7436:3;7440:1;7436:6;;;;;;;;:::i;:::-;;;;;;;;;;;;7417:26;;;;;;;;;;;;-1:-1:-1;7417:26:5;;;;:40;7409:65;;;;;;;31133:2:31;7409:65:5;;;31115:21:31;31172:2;31152:18;;;31145:30;31211:14;31191:18;;;31184:42;31243:18;;7409:65:5;30931:336:31;7409:65:5;7517:9;:17;;;7488:18;:26;7507:3;7511:1;7507:6;;;;;;;;:::i;:::-;;;;;;;7488:26;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;7587:6;7594:1;7587:9;;;;;;;;:::i;:::-;;;;;;;7553:63;;7568:9;:17;;;7553:63;;;7598:3;7602:1;7598:6;;;;;;;;:::i;:::-;;;;;;;7606:9;7553:63;;;;;;31476:34:31;31464:47;;;;31446:66;;31543:2;31528:18;;31521:34;31434:2;31419:18;;31272:289;7553:63:5;;;;;;;;7047:3;;7015:612;;;-1:-1:-1;7703:3:5;;6623:1091;-1:-1:-1;;;;;;6623:1091:5:o;9163:524::-;9292:11;;9236:21;;9292:11;;;9313:48;;;;;;;32868:2:31;9313:48:5;;;32850:21:31;32907:1;32887:18;;;32880:29;32945:11;32925:18;;;32918:39;32974:18;;9313:48:5;32666:332:31;9313:48:5;9406:27;;9461:20;;;;;-1:-1:-1;9372:19:5;9492:126;9509:12;:19;;;:26;9507:1;:28;9492:126;;;9556:7;:13;;;9570:12;:19;;;9590:1;9570:22;;;;;;;;:::i;:::-;;;;;;;9594:12;9556:51;;;;;;;;;;;;;;;33205:4:31;33193:17;;;;33175:36;;33259:42;33247:55;33242:2;33227:18;;33220:83;33163:2;33148:18;;33003:306;9556:51:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9537:3:5;;;;;-1:-1:-1;9492:126:5;;-1:-1:-1;9492:126:5;;-1:-1:-1;9644:36:5;9667:13;9644:20;;;;:36;:::i;6721:441:4:-;6901:22;6925:17;6954:55;6981:6;6989:19;6954:26;:55::i;:::-;7031:28;7040:6;7048:10;7031:8;:28::i;:::-;7019:40;;7086:9;7077:6;:18;7069:41;;;;;;;33516:2:31;7069:41:4;;;33498:21:31;33555:2;33535:18;;;33528:30;33594:12;33574:18;;;33567:40;33624:18;;7069:41:4;33314:334:31;7069:41:4;7137:18;7146:9;7137:6;:18;:::i;:::-;7120:35;;6721:441;;;;;;:::o;7168:316::-;7315:15;;;;7368:14;;353:5;7306:35;:24;;;;;:35;;;;;7356:26;;7353:57;;;-1:-1:-1;7396:14:4;;7353:57;7435:10;:14;;;7423:9;:26;7420:57;;;-1:-1:-1;7463:14:4;;;;7168:316;-1:-1:-1;7168:316:4:o;2892:117:2:-;1949:19;:17;:19::i;:::-;846:66;1092:54;;;;2962:4:::1;1092:54:::0;;;2982:20:::1;734:10:19::0;2989:12:2::1;655:96:19::0;6239:476:4;6346:12;6403:6;6378:21;:31;;6370:59;;;;;;;34044:2:31;6370:59:4;;;34026:21:31;34083:2;34063:18;;;34056:30;34122:17;34102:18;;;34095:45;34157:18;;6370:59:4;33842:339:31;6370:59:4;6454:38;;:14;;;;6477:6;;6454:38;;;;6477:6;6454:14;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6440:52;;;;;6507:7;6502:207;;6549:9;6535:32;;;6560:6;6535:32;;;;5986:25:31;;5974:2;5959:18;;5840:177;6535:32:4;;;;;;;;6582:13;1280:6:0;;;;;;;6601:21:4;;6631:6;6601:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6581:65;;;6668:8;6660:38;;;;;;;34598:2:31;6660:38:4;;;34580:21:31;34637:2;34617:18;;;34610:30;34676:19;34656:18;;;34649:47;34713:18;;6660:38:4;34396:341:31;6660:38:4;6516:193;6239:476;;;;:::o;2519:272:1:-;2748:34;;;34946:42:31;34934:55;;2748:34:1;;;34916:74:31;1199:66:1;35006:18:31;;;34999:34;;;;2581:31:1;;2711:73;;34889:18:31;;2748:34:1;;;;;;;;;;;;2738:45;;;;;;1038:4:3;880:170;6674:198:17;6757:12;6788:77;6809:6;6817:4;6788:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;6781:84;6674:198;-1:-1:-1;;;6674:198:17:o;4691:859:5:-;4854:17;4882:73;4909:9;:16;;;4927:8;:27;;;4882:26;:73::i;:::-;4969:11;4965:289;;;5008:46;5017:9;:16;;;5035:8;:18;;;5008:8;:46::i;:::-;4996:58;;5095:9;5076;:16;;;:28;5068:51;;;;;;;33516:2:31;5068:51:5;;;33498:21:31;33555:2;33535:18;;;33528:30;33594:12;33574:18;;;33567:40;33624:18;;5068:51:5;33314:334:31;5068:51:5;5144:16;;;:29;;;;;;;5220:10;;5189:54;;5220:10;;5164:9;5189:22;:54::i;:::-;;4965:289;5312:16;;;;5263:19;;;;:66;;;;5312:16;;5263:66;:::i;:::-;;;;;-1:-1:-1;5357:19:5;;;;5340:37;;6203:23:4;;;;;;;;;;;;;;;;:10;:23;6129:104;5340:37:5;5387:18;5408:16;:14;:16::i;:::-;5387:37;;5461:9;:17;;;5439:69;;5448:11;5439:69;;;5480:9;:16;;;5498:9;5439:69;;;;;;13044:25:31;;;13100:2;13085:18;;13078:34;13032:2;13017:18;;12870:248;5439:69:5;;;;;;;;5519:24;5526:9;:16;;;5519:6;:24::i;:::-;4844:706;;4691:859;;;:::o;7720:796::-;7802:15;7820:32;;;:18;:32;;;;;;;;;7862:53;;;;;;;23304:2:31;7862:53:5;;;23286:21:31;23343:2;23323:18;;;23316:30;23382:21;23362:18;;;23355:49;23421:18;;7862:53:5;23102:343:31;7862:53:5;7932:32;;;;:18;:32;;;;;;;;7925:39;;;;;;8009:11;:26;;8063:23;;;;;;;7925:39;8009:26;;;;7932:32;8009:26;;8063:21;;:23;;;;;;;;;;7932:32;8009:26;8063:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;;8112:12;8063:62;;;;;;;;;;;;;5986:25:31;;5974:2;5959:18;;5840:177;8063:62:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:69;;;8197:109;;;;;;;;24837:25:31;;;24878:18;;;24871:34;;;8289:4:5;24921:18:31;;;24914:83;8063:69:5;;-1:-1:-1;8166:21:5;;8197:16;;;;;;24810:18:31;;8197:109:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8365:6;8348:13;8324:21;:37;;;;:::i;:::-;:47;8316:75;;;;;;;25532:2:31;8316:75:5;;;25514:21:31;25571:2;25551:18;;;25544:30;25610:17;25590:18;;;25583:45;25645:18;;8316:75:5;25330:339:31;8316:75:5;8401:48;8432:7;8442:6;8401:22;:48::i;:::-;;8496:12;8489:5;8480:7;8464:45;;;;;;;;;;;;7792:724;;;;7720:796;;:::o;8898:259::-;9031:21;9062:24;9110:40;9129:12;9143:6;9110:18;:40::i;:::-;9103:47;;;;8898:259;;;;;;:::o;5556:593::-;5607:45;;;;;;;;5641:11;5607:45;;;;;;;;;;;;;;;;;;;;;;;;;:31;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5607:45:5;;;;-1:-1:-1;;5696:27:5;;5607:45;;-1:-1:-1;5662:19:5;;-1:-1:-1;5662:19:5;5782:49;5607:45;5823:6;5782:18;:49::i;:::-;5734:97;;;;5845:9;5841:302;5858:6;:13;5856:1;:15;5841:302;;;5892:7;:15;;;5915:3;5919:1;5915:6;;;;;;;;:::i;:::-;;;;;;;5892:240;;5940:6;5947:1;5940:9;;;;;;;;:::i;:::-;;;;;;;5983:3;5987:1;5983:6;;;;;;;;:::i;:::-;;;;;;;;;;;5892:240;;;;;;;;;;35335:4:31;35323:17;;;5892:240:5;;;35305:36:31;35389:34;35377:47;35357:18;;;35350:75;6032:4:5;35441:18:31;;;35434:83;6069:5:5;35533:18:31;;;35526:50;;;35592:19;;;35585:51;35277:19;;5892:240:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5873:3:5;;;;;-1:-1:-1;5841:302:5;;-1:-1:-1;;5841:302:5;;;5597:552;;;;5556:593;:::o;874:88:4:-;943:10;:12;;918:6;;943:12;;;;;918:6;943:12;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;936:19;;874:88;:::o;2797:291:1:-;2871:19;;;;2867:215;;2906:42;2951:21;2966:5;2951:14;:21::i;:::-;2990:16;;2906:66;;-1:-1:-1;2990:24:1;;;:16;;;;:24;;;2986:48;;3023:11;;;;;;;;;;;;;;2986:48;3048:23;;;;;;;;;;;;2797:291;;:::o;2655:102:2:-;2718:8;:6;:8::i;:::-;2713:37;;2735:15;;;;;;;;;;;;;;2433:187:0;2506:16;2525:6;;;2541:17;;;2525:6;2541:17;;;;;;;;;2573:40;;2525:6;;;;;;;2541:17;;2525:6;;2573:40;;;2496:124;2433:187;:::o;3815:404:3:-;3889:20;;;;3885:328;;3929:43;;;;;;;1839:66;3929:43;;;;;;:51;;;:43;;;;:51;;;3925:76;;3989:12;;;;;;;;;;;;;;3925:76;4015:43;;;;;;;1839:66;4015:43;;;;;:50;;;;;;;;;;;;;;;4080:122;;1839:66;4089:46;;;;;;;-1:-1:-1;4089:46:3;;;;;;;;;;;;;;;;;;;;1949:148:5;;:::o;4080:122:3:-;4154:48;1839:66;4194:6;4154:38;:48::i;4811:208:4:-;4948:64;4961:49;4985:5;4992:11;5005:4;4961:23;:49::i;7490:246::-;7621:23;;:33;-1:-1:-1;7621:33:4;7613:53;;;;;;;36063:2:31;7613:53:4;;;36045:21:31;36102:1;36082:18;;;36075:29;36140:9;36120:18;;;36113:37;36167:18;;7613:53:4;35861:330:31;7613:53:4;7711:6;7684:19;:23;;;:33;;7676:53;;;;;;;36398:2:31;7676:53:4;;;36380:21:31;36437:1;36417:18;;;36410:29;36475:9;36455:18;;;36448:37;36502:18;;7676:53:4;36196:330:31;7058:325:17;7199:12;7224;7238:23;7265:6;:19;;7285:4;7265:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7223:67;;;;7307:69;7334:6;7342:7;7351:10;7363:12;7307:26;:69::i;:::-;7300:76;7058:325;-1:-1:-1;;;;;;7058:325:17:o;8522:370:5:-;8653:21;8684:24;8733:12;:19;;;:26;8763:1;8733:31;8725:57;;;;;;;37025:2:31;8725:57:5;;;37007:21:31;37064:2;37044:18;;;37037:30;37103:15;37083:18;;;37076:43;37136:18;;8725:57:5;36823:337:31;8725:57:5;8801:19;;;;8840:16;;;8854:1;8840:16;;;;;;;;;8801:19;;-1:-1:-1;8840:16:5;;;;;;;;;;;;-1:-1:-1;8840:16:5;8830:26;;8879:6;8866:7;8874:1;8866:10;;;;;;;;:::i;:::-;;;;;;:19;;;;;;;;;;;8522:370;;;;;:::o;1276:311:3:-;1362:10;;1348:11;1382:199;1399:3;1397:1;:5;1382:199;;;1430:3;1434:1;1430:6;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;1422:14;;;;1419:122;;1465:3;1469:5;1473:1;1469:3;:5;:::i;:::-;1465:10;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;1456:3;1460:1;1456:6;;;;;;;;:::i;:::-;;;;;;;;;:19;;;;;;;;;;;;;;;;;;1493:3;:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1276:311:3:o;1419:122::-;1565:3;;1382:199;;7671:628:17;7851:12;7879:7;7875:418;;;7906:10;:17;7927:1;7906:22;7902:286;;1713:19:18;;;;8113:60:17;;;;;;;37556:2:31;8113:60:17;;;37538:21:31;37595:2;37575:18;;;37568:30;37634:31;37614:18;;;37607:59;37683:18;;8113:60:17;37354:353:31;8113:60:17;-1:-1:-1;8208:10:17;8201:17;;7875:418;8249:33;8257:10;8269:12;8980:17;;:21;8976:379;;9208:10;9202:17;9264:15;9251:10;9247:2;9243:19;9236:44;8976:379;9331:12;9324:20;;;;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;211:154:31;297:42;290:5;286:54;279:5;276:65;266:93;;355:1;352;345:12;370:247;429:6;482:2;470:9;461:7;457:23;453:32;450:52;;;498:1;495;488:12;450:52;537:9;524:23;556:31;581:5;556:31;:::i;827:171::-;894:20;;954:18;943:30;;933:41;;923:69;;988:1;985;978:12;923:69;827:171;;;:::o;1003:184::-;1055:77;1052:1;1045:88;1152:4;1149:1;1142:15;1176:4;1173:1;1166:15;1192:253;1264:2;1258:9;1306:4;1294:17;;1341:18;1326:34;;1362:22;;;1323:62;1320:88;;;1388:18;;:::i;:::-;1424:2;1417:22;1192:253;:::o;1450:257::-;1522:4;1516:11;;;1554:17;;1601:18;1586:34;;1622:22;;;1583:62;1580:88;;;1648:18;;:::i;1712:334::-;1783:2;1777:9;1839:2;1829:13;;1844:66;1825:86;1813:99;;1942:18;1927:34;;1963:22;;;1924:62;1921:88;;;1989:18;;:::i;:::-;2025:2;2018:22;1712:334;;-1:-1:-1;1712:334:31:o;2051:186::-;2114:4;2147:18;2139:6;2136:30;2133:56;;;2169:18;;:::i;:::-;-1:-1:-1;2214:1:31;2210:14;2226:4;2206:25;;2051:186::o;2242:156::-;2308:20;;2368:4;2357:16;;2347:27;;2337:55;;2388:1;2385;2378:12;2403:1055;2460:5;2513:3;2506:4;2498:6;2494:17;2490:27;2480:55;;2531:1;2528;2521:12;2480:55;2567:6;2554:20;2593:4;2617:63;2633:46;2676:2;2633:46;:::i;:::-;2617:63;:::i;:::-;2714:15;;;2776:4;2819:13;;;2807:26;;2803:35;;;2745:12;;;;2702:3;2850:15;;;2847:35;;;2878:1;2875;2868:12;2847:35;2914:2;2906:6;2902:15;2926:503;2942:6;2937:3;2934:15;2926:503;;;3018:2;3012:3;3007;3003:13;2999:22;2996:112;;;3062:1;3091:2;3087;3080:14;2996:112;3134:22;;:::i;:::-;3183:21;3200:3;3183:21;:::i;:::-;3169:36;;3254:12;;;3241:26;3225:14;;;3218:50;3291:2;3342:12;;;3329:26;3313:14;;;3306:50;3369:18;;3407:12;;;;2959;;2926:503;;3463:893;3616:6;3624;3632;3676:9;3667:7;3663:23;3706:3;3702:2;3698:12;3695:32;;;3723:1;3720;3713:12;3695:32;3746:28;3764:9;3746:28;:::i;:::-;3736:38;;3867:4;3798:66;3794:2;3790:75;3786:86;3783:106;;;3885:1;3882;3875:12;3783:106;;3911:22;;:::i;:::-;3985:2;3974:9;3970:18;3957:32;3998:33;4023:7;3998:33;:::i;:::-;4040:22;;4122:4;4107:20;;4094:34;4089:2;4078:14;;4071:58;4047:5;-1:-1:-1;4204:2:31;4189:18;;4176:32;4231:18;4220:30;;4217:50;;;4263:1;4260;4253:12;4217:50;4286:64;4342:7;4333:6;4322:9;4318:22;4286:64;:::i;:::-;4276:74;;;3463:893;;;;;:::o;4361:681::-;4532:2;4584:21;;;4654:13;;4557:18;;;4676:22;;;4503:4;;4532:2;4755:15;;;;4729:2;4714:18;;;4503:4;4798:218;4812:6;4809:1;4806:13;4798:218;;;4877:13;;4892:42;4873:62;4861:75;;4991:15;;;;4956:12;;;;4834:1;4827:9;4798:218;;5047:180;5106:6;5159:2;5147:9;5138:7;5134:23;5130:32;5127:52;;;5175:1;5172;5165:12;5127:52;-1:-1:-1;5198:23:31;;5047:180;-1:-1:-1;5047:180:31:o;6022:163::-;6089:20;;6149:10;6138:22;;6128:33;;6118:61;;6175:1;6172;6165:12;6190:415;6276:6;6329:2;6317:9;6308:7;6304:23;6300:32;6297:52;;;6345:1;6342;6335:12;6297:52;6371:22;;:::i;:::-;6429:9;6416:23;6409:5;6402:38;6500:2;6489:9;6485:18;6472:32;6467:2;6460:5;6456:14;6449:56;6537:37;6570:2;6559:9;6555:18;6537:37;:::i;:::-;6532:2;6521:14;;6514:61;6525:5;6190:415;-1:-1:-1;;;6190:415:31:o;6921:279::-;6698:12;;6712:10;6694:29;6682:42;;6777:4;6766:16;;;6760:23;6785:42;6756:72;6740:14;;;6733:96;6882:4;6871:16;;;6865:23;6890:18;6861:48;6845:14;;;6838:72;7127:2;7112:18;;7139:55;6610:306;7397:1044;7455:5;7503:4;7491:9;7486:3;7482:19;7478:30;7475:50;;;7521:1;7518;7511:12;7475:50;7543:22;;:::i;:::-;7534:31;;7602:9;7589:23;7621:33;7646:7;7621:33;:::i;:::-;7663:22;;7704:2;7742:18;;;7729:32;7784:18;7773:30;;7770:50;;;7816:1;7813;7806:12;7770:50;7839:22;;7892:4;7884:13;;7880:23;-1:-1:-1;7870:51:31;;7917:1;7914;7907:12;7870:51;7953:2;7940:16;7976:63;7992:46;8035:2;7992:46;:::i;7976:63::-;8073:15;;;8155:1;8151:10;;;;8143:19;;8139:28;;;8104:12;;;;8179:15;;;8176:35;;;8207:1;8204;8197:12;8176:35;8231:11;;;;8251:146;8267:6;8262:3;8259:15;8251:146;;;8333:21;8350:3;8333:21;:::i;:::-;8321:34;;8284:12;;;;8375;;;;8251:146;;;8429:5;8424:2;8417:5;8413:14;8406:29;;;;;;7397:1044;;;;:::o;8446:488::-;8543:6;8551;8604:2;8592:9;8583:7;8579:23;8575:32;8572:52;;;8620:1;8617;8610:12;8572:52;8659:9;8646:23;8678:31;8703:5;8678:31;:::i;:::-;8728:5;-1:-1:-1;8784:2:31;8769:18;;8756:32;8811:18;8800:30;;8797:50;;;8843:1;8840;8833:12;8797:50;8866:62;8920:7;8911:6;8900:9;8896:22;8866:62;:::i;:::-;8856:72;;;8446:488;;;;;:::o;9325:353::-;9413:6;9466:2;9454:9;9445:7;9441:23;9437:32;9434:52;;;9482:1;9479;9472:12;9434:52;9522:9;9509:23;9555:18;9547:6;9544:30;9541:50;;;9587:1;9584;9577:12;9541:50;9610:62;9664:7;9655:6;9644:9;9640:22;9610:62;:::i;9683:188::-;9751:20;;9811:34;9800:46;;9790:57;;9780:85;;9861:1;9858;9851:12;9876:661;9971:6;10024:3;10012:9;10003:7;9999:23;9995:33;9992:53;;;10041:1;10038;10031:12;9992:53;10074:2;10068:9;10116:3;10108:6;10104:16;10186:6;10174:10;10171:22;10150:18;10138:10;10135:34;10132:62;10129:88;;;10197:18;;:::i;:::-;10237:10;10233:2;10226:22;;10285:9;10272:23;10264:6;10257:39;10357:2;10346:9;10342:18;10329:32;10324:2;10316:6;10312:15;10305:57;10395:38;10429:2;10418:9;10414:18;10395:38;:::i;:::-;10390:2;10382:6;10378:15;10371:63;10467:38;10501:2;10490:9;10486:18;10467:38;:::i;:::-;10462:2;10450:15;;10443:63;10454:6;9876:661;-1:-1:-1;;;9876:661:31:o;10542:794::-;10630:6;10638;10646;10654;10707:2;10695:9;10686:7;10682:23;10678:32;10675:52;;;10723:1;10720;10713:12;10675:52;10762:9;10749:23;10781:31;10806:5;10781:31;:::i;:::-;10831:5;-1:-1:-1;10883:2:31;10868:18;;10855:32;;-1:-1:-1;10938:2:31;10923:18;;10910:32;10961:18;10991:14;;;10988:34;;;11018:1;11015;11008:12;10988:34;11056:6;11045:9;11041:22;11031:32;;11101:7;11094:4;11090:2;11086:13;11082:27;11072:55;;11123:1;11120;11113:12;11072:55;11163:2;11150:16;11189:2;11181:6;11178:14;11175:34;;;11205:1;11202;11195:12;11175:34;11250:7;11245:2;11236:6;11232:2;11228:15;11224:24;11221:37;11218:57;;;11271:1;11268;11261:12;11218:57;10542:794;;;;-1:-1:-1;;11302:2:31;11294:11;;-1:-1:-1;;;10542:794:31:o;11341:250::-;11426:1;11436:113;11450:6;11447:1;11444:13;11436:113;;;11526:11;;;11520:18;11507:11;;;11500:39;11472:2;11465:10;11436:113;;;-1:-1:-1;;11583:1:31;11565:16;;11558:27;11341:250::o;11596:329::-;11637:3;11675:5;11669:12;11702:6;11697:3;11690:19;11718:76;11787:6;11780:4;11775:3;11771:14;11764:4;11757:5;11753:16;11718:76;:::i;:::-;11839:2;11827:15;11844:66;11823:88;11814:98;;;;11914:4;11810:109;;11596:329;-1:-1:-1;;11596:329:31:o;11930:298::-;12113:6;12106:14;12099:22;12088:9;12081:41;12158:2;12153;12142:9;12138:18;12131:30;12062:4;12178:44;12218:2;12207:9;12203:18;12195:6;12178:44;:::i;12233:632::-;12404:2;12456:21;;;12526:13;;12429:18;;;12548:22;;;12375:4;;12404:2;12627:15;;;;12601:2;12586:18;;;12375:4;12670:169;12684:6;12681:1;12678:13;12670:169;;;12745:13;;12733:26;;12814:15;;;;12779:12;;;;12706:1;12699:9;12670:169;;13686:248;13754:6;13762;13815:2;13803:9;13794:7;13790:23;13786:32;13783:52;;;13831:1;13828;13821:12;13783:52;-1:-1:-1;;13854:23:31;;;13924:2;13909:18;;;13896:32;;-1:-1:-1;13686:248:31:o;13939:626::-;14036:6;14044;14097:2;14085:9;14076:7;14072:23;14068:32;14065:52;;;14113:1;14110;14103:12;14065:52;14153:9;14140:23;14182:18;14223:2;14215:6;14212:14;14209:34;;;14239:1;14236;14229:12;14209:34;14277:6;14266:9;14262:22;14252:32;;14322:7;14315:4;14311:2;14307:13;14303:27;14293:55;;14344:1;14341;14334:12;14293:55;14384:2;14371:16;14410:2;14402:6;14399:14;14396:34;;;14426:1;14423;14416:12;14396:34;14479:7;14474:2;14464:6;14461:1;14457:14;14453:2;14449:23;14445:32;14442:45;14439:65;;;14500:1;14497;14490:12;14439:65;14531:2;14523:11;;;;;14553:6;;-1:-1:-1;13939:626:31;;-1:-1:-1;;;;13939:626:31:o;14570:859::-;14730:4;14759:2;14799;14788:9;14784:18;14829:2;14818:9;14811:21;14852:6;14887;14881:13;14918:6;14910;14903:22;14956:2;14945:9;14941:18;14934:25;;15018:2;15008:6;15005:1;15001:14;14990:9;14986:30;14982:39;14968:53;;15056:2;15048:6;15044:15;15077:1;15087:313;15101:6;15098:1;15095:13;15087:313;;;15190:66;15178:9;15170:6;15166:22;15162:95;15157:3;15150:108;15281:39;15313:6;15304;15298:13;15281:39;:::i;:::-;15271:49;-1:-1:-1;15378:12:31;;;;15343:15;;;;15123:1;15116:9;15087:313;;;-1:-1:-1;15417:6:31;;14570:859;-1:-1:-1;;;;;;;14570:859:31:o;15434:502::-;15529:6;15582:2;15570:9;15561:7;15557:23;15553:32;15550:52;;;15598:1;15595;15588:12;15550:52;15624:22;;:::i;:::-;15669:28;15687:9;15669:28;:::i;:::-;15662:5;15655:43;15750:2;15739:9;15735:18;15722:32;15763:33;15788:7;15763:33;:::i;:::-;15823:2;15812:14;;15805:31;15868:37;15901:2;15886:18;;15868:37;:::i;15941:857::-;16120:2;16131:21;;;16233:13;;16248:42;16229:62;16209:18;;;16202:90;16327:15;;;16321:22;16381:4;16359:20;;;16352:34;16435:19;;16190:2;16175:18;;16463:22;;;16091:4;;16120:2;16543:21;;;16091:4;;16516:3;16501:19;;;16592:180;16606:6;16603:1;16600:13;16592:180;;;16671:13;;16686:4;16667:24;16655:37;;16747:15;;;;16628:1;16621:9;;;;;16712:12;;;;16592:180;;;-1:-1:-1;16789:3:31;15941:857;-1:-1:-1;;;;;;15941:857:31:o;16803:969::-;16887:6;16918:2;16961;16949:9;16940:7;16936:23;16932:32;16929:52;;;16977:1;16974;16967:12;16929:52;17017:9;17004:23;17050:18;17042:6;17039:30;17036:50;;;17082:1;17079;17072:12;17036:50;17105:22;;17158:4;17150:13;;17146:27;-1:-1:-1;17136:55:31;;17187:1;17184;17177:12;17136:55;17223:2;17210:16;17246:63;17262:46;17305:2;17262:46;:::i;17246:63::-;17343:15;;;17425:1;17421:10;;;;17413:19;;17409:28;;;17374:12;;;;17449:19;;;17446:39;;;17481:1;17478;17471:12;17446:39;17505:11;;;;17525:217;17541:6;17536:3;17533:15;17525:217;;;17621:3;17608:17;17638:31;17663:5;17638:31;:::i;:::-;17682:18;;17558:12;;;;17720;;;;17525:217;;;17761:5;16803:969;-1:-1:-1;;;;;;;16803:969:31:o;17777:512::-;17899:6;17907;17915;17968:2;17956:9;17947:7;17943:23;17939:32;17936:52;;;17984:1;17981;17974:12;17936:52;18007:28;18025:9;18007:28;:::i;:::-;17997:38;;18082:2;18071:9;18067:18;18054:32;18044:42;;18137:2;18126:9;18122:18;18109:32;18164:18;18156:6;18153:30;18150:50;;;18196:1;18193;18186:12;18294:301;18382:1;18375:5;18372:12;18362:200;;18418:77;18415:1;18408:88;18519:4;18516:1;18509:15;18547:4;18544:1;18537:15;18362:200;18571:18;;18294:301::o;18600:648::-;6698:12;;6712:10;6694:29;6682:42;;6777:4;6766:16;;;6760:23;6785:42;6756:72;6740:14;;;6733:96;6882:4;6871:16;;;6865:23;6890:18;6861:48;6845:14;;;6838:72;18943:3;18928:19;;19020:60;19076:2;19065:9;19061:18;19053:6;19020:60;:::i;:::-;19136:42;19127:6;19121:13;19117:62;19111:3;19100:9;19096:19;19089:91;19235:4;19227:6;19223:17;19217:24;19211:3;19200:9;19196:19;19189:53;18600:648;;;;;;:::o;19253:184::-;19305:77;19302:1;19295:88;19402:4;19399:1;19392:15;19426:4;19423:1;19416:15;22489:271;22672:6;22664;22659:3;22646:33;22628:3;22698:16;;22723:13;;;22698:16;22489:271;-1:-1:-1;22489:271:31:o;23450:274::-;23543:6;23596:2;23584:9;23575:7;23571:23;23567:32;23564:52;;;23612:1;23609;23602:12;23564:52;23644:9;23638:16;23663:31;23688:5;23663:31;:::i;23729:885::-;23838:6;23891:3;23879:9;23870:7;23866:23;23862:33;23859:53;;;23908:1;23905;23898:12;23859:53;23941:2;23935:9;23983:3;23975:6;23971:16;24053:6;24041:10;24038:22;24017:18;24005:10;24002:34;23999:62;23996:88;;;24064:18;;:::i;:::-;24104:10;24100:2;24093:22;;24145:9;24139:16;24131:6;24124:32;24210:2;24199:9;24195:18;24189:25;24184:2;24176:6;24172:15;24165:50;24269:2;24258:9;24254:18;24248:25;24243:2;24235:6;24231:15;24224:50;24328:2;24317:9;24313:18;24307:25;24302:2;24294:6;24290:15;24283:50;24388:3;24377:9;24373:19;24367:26;24361:3;24353:6;24349:16;24342:52;24449:3;24438:9;24434:19;24428:26;24422:3;24414:6;24410:16;24403:52;24498:3;24487:9;24483:19;24477:26;24512:31;24537:5;24512:31;:::i;:::-;24571:3;24559:16;;24552:31;24563:6;23729:885;-1:-1:-1;;;23729:885:31:o;25008:184::-;25060:77;25057:1;25050:88;25157:4;25154:1;25147:15;25181:4;25178:1;25171:15;25197:128;25264:9;;;25285:11;;;25282:37;;;25299:18;;:::i;26010:580::-;26087:4;26093:6;26153:11;26140:25;26243:66;26232:8;26216:14;26212:29;26208:102;26188:18;26184:127;26174:155;;26325:1;26322;26315:12;26174:155;26352:33;;26404:20;;;-1:-1:-1;26447:18:31;26436:30;;26433:50;;;26479:1;26476;26469:12;26433:50;26512:4;26500:17;;-1:-1:-1;26543:14:31;26539:27;;;26529:38;;26526:58;;;26580:1;26577;26570:12;26595:440;26824:6;26816;26811:3;26798:33;26780:3;26859:6;26854:3;26850:16;26886:1;26882:2;26875:13;26917:6;26911:13;26933:65;26991:6;26987:2;26980:4;26972:6;26968:17;26933:65;:::i;:::-;27014:15;;26595:440;-1:-1:-1;;;;;26595:440:31:o;28068:125::-;28133:9;;;28154:10;;;28151:36;;;28167:18;;:::i;29219:468::-;6698:12;;6712:10;6694:29;6682:42;;6777:4;6766:16;;;6760:23;6785:42;6756:72;6740:14;;;6733:96;6882:4;6871:16;;;6865:23;6890:18;6861:48;6845:14;;;6838:72;29500:3;29485:19;;29577:60;29633:2;29622:9;29618:18;29610:6;29577:60;:::i;:::-;29674:6;29668:3;29657:9;29653:19;29646:35;29219:468;;;;;;:::o;30742:184::-;30812:6;30865:2;30853:9;30844:7;30840:23;30836:32;30833:52;;;30881:1;30878;30871:12;30833:52;-1:-1:-1;30904:16:31;;30742:184;-1:-1:-1;30742:184:31:o;31898:197::-;31966:34;32020:10;;;32032;;;32016:27;;32055:11;;;32052:37;;;32069:18;;:::i;32461:200::-;32530:34;32597:10;;;32585;;;32581:27;;32620:12;;;32617:38;;;32635:18;;:::i;35647:209::-;35685:3;35713:18;35766:2;35759:5;35755:14;35793:2;35784:7;35781:15;35778:41;;35799:18;;:::i;:::-;35848:1;35835:15;;35647:209;-1:-1:-1;;;35647:209:31:o;36531:287::-;36660:3;36698:6;36692:13;36714:66;36773:6;36768:3;36761:4;36753:6;36749:17;36714:66;:::i;:::-;36796:16;;;;;36531:287;-1:-1:-1;;36531:287:31:o;37165:184::-;37217:77;37214:1;37207:88;37314:4;37311:1;37304:15;37338:4;37335:1;37328:15;37712:219;37861:2;37850:9;37843:21;37824:4;37881:44;37921:2;37910:9;37906:18;37898:6;37881:44;:::i
Swarm Source
ipfs://9c771ad8a1e0b048b08be8f0d36d466b7655b6a8b9fede21ff34f40f4ef3f6da
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.