Spend less on fees, more on crypto. Buy crypto easily with MoonPay Balance. 20M+ users trust MoonPay worldwide.
Ready to onboard to Ethereum? With MetaMask Portfolio, you're in control.
Don’t invest unless you’re prepared to lose all the money you invest.
Ready to simplify your web3 experience? Try the all-in-one web3 app trusted by millions worldwide.
Available on 9 networks: Ethereum mainnet, Linea, Polygon, Optimism, BNB Chain, zkSync Era, Base, Avalanche.
Everyday giveaways up to 100 ETH, Lucky Spins. Deposit BONUS 300% and Cashbacks!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Slots, Roulette, Poker & more - Proud sponsors of UFC, Everton & StakeF1 team!
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Anonymous play on awesome games - sign up now for 25 free jackpot spins - worth $100s!
100s of games, generous bonuses, 20+ years of trusted gaming. Join CryptoWins & start winning today!
Overview
ETH Balance
Eth Value
$22,426,165.47 (@ $3,374.93/ETH)Token Holdings
Could not find any matches!
- ERC-20 Tokens (29)30.72196401 LINKChainLink To... (LINK)$733.33@23.87111,858.10117084 PSYOPPsyop (PSYOP)$3.28@0.0044.881674 USDCUSDC (USDC)$44.83@0.998841,292,938.5214074 BENBen$0.16@0.001 DMusdERC-20: Dece... (DMusd)1 HSFHillstone.Finance$0.01@0.0078100,000 MANERC-20: Huma... (MAN)100 ICGERC-20: Inve... (ICG)17,174.66742946 LOFEERC-20: LOFE (LOFE)48,999,999.02 MAILERC-20: Mail... (MAIL)91.416525 PYUSDPayPal USD$91.28@0.998520,000,000 PSYOPERC-20: PSYD... (PSYOP)0.0001 HQGERC-20: 环球股 (HQG)2 APUApu Apustaja$0.00@0.00070.01 SHEESHASheesha Finance$0.04@3.9764,999.99 TokenERC-20 TOKEN*[Suspicious]245.44 TokenERC-20 TOKEN*[Suspicious]1.4 TokenERC-20 TOKEN*[Suspicious]32 TokenERC-20 TOKEN*[Suspicious]1.7 TokenERC-20 TOKEN*[Suspicious]4,999.99 TokenERC-20 TOKEN*[Suspicious]1.4 TokenERC-20 TOKEN*[Spam]1.4 TokenERC-20 TOKEN*[Spam]132.84 TokenERC-20 TOKEN*[Spam]3,999.99 TokenERC-20 TOKEN*[Spam]1,049 TokenERC-20 TOKEN*[Spam]3,999.99 TokenERC-20 TOKEN*[Spam]4,600,000 TokenERC-20 TOKEN*[Spam]25,000 TokenERC-20 TOKEN*[Spam]NFT Tokens (14)claim rewards on apylink.orgapylink.orgERC-1155claim rewards on link-get.comlink-get.comERC-1155claim rewards on staked-eth.netstaked-eth.netERC-1155ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]
More Info
Private Name Tags
ContractCreator
Multichain Info
2 addresses found via- Transactions
- Internal Transactions
- Token Transfers (ERC-20)
- NFT Transfers
- Contract
- Events
- Analytics
- Multichain Portfolio
- Cards New
Advanced Filter- Filter by Tx Type:
- Tx
- Internal Tx
- ERC-20
- NFTs
Latest 25 from a total of 1,522,090 transactions
Transaction Hash MethodBlockFromToBond Withdrawal 21469160 2024-12-24 1:50:11 2 mins ago 1735005011 IN 0 ETH$0.00 0.00074986 6.49601284 Bond Withdrawal 21469158 2024-12-24 1:49:47 3 mins ago 1735004987 IN 0 ETH$0.00 0.000779 6.74775366 Bond Withdrawal 21469158 2024-12-24 1:49:47 3 mins ago 1735004987 IN 0 ETH$0.00 0.000779 6.74775366 Bond Withdrawal 21469155 2024-12-24 1:49:11 3 mins ago 1735004951 IN 0 ETH$0.00 0.00096729 6.88785823 Bond Withdrawal 21469148 2024-12-24 1:47:47 5 mins ago 1735004867 IN 0 ETH$0.00 0.0007636 6.61503544 Bond Withdrawal 21469143 2024-12-24 1:46:47 6 mins ago 1735004807 IN 0 ETH$0.00 0.00095255 6.78229064 Bond Withdrawal 21469135 2024-12-24 1:45:11 7 mins ago 1735004711 IN 0 ETH$0.00 0.00080753 6.99488383 Bond Withdrawal 21469134 2024-12-24 1:44:59 8 mins ago 1735004699 IN 0 ETH$0.00 0.0007792 6.74875526 Bond Withdrawal 21469133 2024-12-24 1:44:47 8 mins ago 1735004687 IN 0 ETH$0.00 0.00076773 6.65079769 Bond Withdrawal 21469130 2024-12-24 1:44:11 8 mins ago 1735004651 IN 0 ETH$0.00 0.00077634 6.72537307 Bond Withdrawal 21469125 2024-12-24 1:43:11 9 mins ago 1735004591 IN 0 ETH$0.00 0.00076139 6.59447635 Bond Withdrawal 21469121 2024-12-24 1:42:23 10 mins ago 1735004543 IN 0 ETH$0.00 0.00078375 6.78887455 Bond Withdrawal 21469112 2024-12-24 1:40:35 12 mins ago 1735004435 IN 0 ETH$0.00 0.00084708 7.33816623 Bond Withdrawal 21469105 2024-12-24 1:39:11 13 mins ago 1735004351 IN 0 ETH$0.00 0.00090236 7.8163055 Bond Withdrawal 21469101 2024-12-24 1:38:23 14 mins ago 1735004303 IN 0 ETH$0.00 0.00083947 7.27150902 Bond Withdrawal 21469092 2024-12-24 1:36:23 16 mins ago 1735004183 IN 0 ETH$0.00 0.00103671 7.38151522 Bond Withdrawal 21469092 2024-12-24 1:36:23 16 mins ago 1735004183 IN 0 ETH$0.00 0.00085218 7.38161522 Bond Withdrawal 21469083 2024-12-24 1:34:35 18 mins ago 1735004075 IN 0 ETH$0.00 0.00083969 7.27345019 Bond Withdrawal 21469070 2024-12-24 1:31:59 21 mins ago 1735003919 IN 0 ETH$0.00 0.00083052 7.19544764 Bond Withdrawal 21469063 2024-12-24 1:30:35 22 mins ago 1735003835 IN 0 ETH$0.00 0.00081511 7.0612785 Bond Withdrawal 21469062 2024-12-24 1:30:23 22 mins ago 1735003823 IN 0 ETH$0.00 0.00079545 6.89092775 Bond Withdrawal 21469059 2024-12-24 1:29:47 23 mins ago 1735003787 IN 0 ETH$0.00 0.00082312 7.12917153 Bond Withdrawal 21469058 2024-12-24 1:29:35 23 mins ago 1735003775 IN 0 ETH$0.00 0.00081785 7.08428846 Bond Withdrawal 21469056 2024-12-24 1:29:11 23 mins ago 1735003751 IN 0 ETH$0.00 0.00084433 7.31285077 Bond Withdrawal 21469055 2024-12-24 1:28:59 24 mins ago 1735003739 IN 0 ETH$0.00 0.00083605 7.24191417 Latest 25 internal transactions (View All)
Advanced mode:Parent Transaction Hash Block FromTo21469160 2024-12-24 1:50:11 2 mins ago 1735005011 0.00110358 ETH$3.72 21469160 2024-12-24 1:50:11 2 mins ago 1735005011 0.01969918 ETH$66.48 21469158 2024-12-24 1:49:47 3 mins ago 1735004987 0.00098025 ETH$3.31 21469158 2024-12-24 1:49:47 3 mins ago 1735004987 0.00615212 ETH$20.76 21469158 2024-12-24 1:49:47 3 mins ago 1735004987 0.00109336 ETH$3.69 21469158 2024-12-24 1:49:47 3 mins ago 1735004987 0.00584105 ETH$19.71 21469155 2024-12-24 1:49:11 3 mins ago 1735004951 0.00103193 ETH$3.48 21469155 2024-12-24 1:49:11 3 mins ago 1735004951 0.01372958 ETH$46.34 21469148 2024-12-24 1:47:47 5 mins ago 1735004867 0.00105262 ETH$3.55 21469148 2024-12-24 1:47:47 5 mins ago 1735004867 0.00271033 ETH$9.15 21469143 2024-12-24 1:46:47 6 mins ago 1735004807 0.00106087 ETH$3.58 21469143 2024-12-24 1:46:47 6 mins ago 1735004807 0.01647493 ETH$55.60 21469135 2024-12-24 1:45:11 7 mins ago 1735004711 0.00108737 ETH$3.67 21469135 2024-12-24 1:45:11 7 mins ago 1735004711 0.00364562 ETH$12.30 21469134 2024-12-24 1:44:59 8 mins ago 1735004699 0.00108717 ETH$3.67 21469134 2024-12-24 1:44:59 8 mins ago 1735004699 0.14515046 ETH$489.87 21469133 2024-12-24 1:44:47 8 mins ago 1735004687 0.00108717 ETH$3.67 21469133 2024-12-24 1:44:47 8 mins ago 1735004687 0.05642908 ETH$190.44 21469130 2024-12-24 1:44:11 8 mins ago 1735004651 0.00107391 ETH$3.62 21469130 2024-12-24 1:44:11 8 mins ago 1735004651 0.00299252 ETH$10.10 21469125 2024-12-24 1:43:11 9 mins ago 1735004591 0.00106041 ETH$3.58 21469125 2024-12-24 1:43:11 9 mins ago 1735004591 0.07203943 ETH$243.13 21469121 2024-12-24 1:42:23 10 mins ago 1735004543 0.00117117 ETH$3.95 21469121 2024-12-24 1:42:23 10 mins ago 1735004543 0.0027249 ETH$9.20 21469112 2024-12-24 1:40:35 12 mins ago 1735004435 0.00121674 ETH$4.11 Loading...LoadingContract Name:L1_ETH_Bridge
Compiler Versionv0.6.12+commit.27d51765
Optimization Enabled:Yes with 50000 runs
Other Settings:default evmVersionContract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import "./L1_Bridge.sol"; /** * @dev A L1_Bridge that uses an ETH as the canonical token */ contract L1_ETH_Bridge is L1_Bridge { constructor (address[] memory bonders, address _governance) public L1_Bridge(bonders, _governance) {} /* ========== Override Functions ========== */ function _transferFromBridge(address recipient, uint256 amount) internal override { (bool success, ) = recipient.call{value: amount}(new bytes(0)); require(success, 'L1_ETH_BRG: ETH transfer failed'); } function _transferToBridge(address /*from*/, uint256 amount) internal override { require(msg.value == amount, "L1_ETH_BRG: Value does not match amount"); } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import "./Bridge.sol"; import "../interfaces/IMessengerWrapper.sol"; /** * @dev L1_Bridge is responsible for the bonding and challenging of TransferRoots. All TransferRoots * originate in the L1_Bridge through `bondTransferRoot` and are propagated up to destination L2s. */ abstract contract L1_Bridge is Bridge { struct TransferBond { address bonder; uint256 createdAt; uint256 totalAmount; uint256 challengeStartTime; address challenger; bool challengeResolved; } /* ========== State ========== */ mapping(uint256 => mapping(bytes32 => uint256)) public transferRootCommittedAt; mapping(bytes32 => TransferBond) public transferBonds; mapping(uint256 => mapping(address => uint256)) public timeSlotToAmountBonded; mapping(uint256 => uint256) public chainBalance; /* ========== Config State ========== */ address public governance; mapping(uint256 => IMessengerWrapper) public crossDomainMessengerWrappers; mapping(uint256 => bool) public isChainIdPaused; uint256 public challengePeriod = 1 days; uint256 public challengeResolutionPeriod = 10 days; uint256 public minTransferRootBondDelay = 15 minutes; uint256 public constant CHALLENGE_AMOUNT_DIVISOR = 10; uint256 public constant TIME_SLOT_SIZE = 4 hours; /* ========== Events ========== */ event TransferSentToL2( uint256 indexed chainId, address indexed recipient, uint256 amount, uint256 amountOutMin, uint256 deadline, address indexed relayer, uint256 relayerFee ); event TransferRootBonded ( bytes32 indexed root, uint256 amount ); event TransferRootConfirmed( uint256 indexed originChainId, uint256 indexed destinationChainId, bytes32 indexed rootHash, uint256 totalAmount ); event TransferBondChallenged( bytes32 indexed transferRootId, bytes32 indexed rootHash, uint256 originalAmount ); event ChallengeResolved( bytes32 indexed transferRootId, bytes32 indexed rootHash, uint256 originalAmount ); /* ========== Modifiers ========== */ modifier onlyL2Bridge(uint256 chainId) { IMessengerWrapper messengerWrapper = crossDomainMessengerWrappers[chainId]; messengerWrapper.verifySender(msg.sender, msg.data); _; } constructor (address[] memory bonders, address _governance) public Bridge(bonders) { governance = _governance; } /* ========== Send Functions ========== */ /** * @notice `amountOutMin` and `deadline` should be 0 when no swap is intended at the destination. * @notice `amount` is the total amount the user wants to send including the relayer fee * @dev Send tokens to a supported layer-2 to mint hToken and optionally swap the hToken in the * AMM at the destination. * @param chainId The chainId of the destination chain * @param recipient The address receiving funds at the destination * @param amount The amount being sent * @param amountOutMin The minimum amount received after attempting to swap in the destination * AMM market. 0 if no swap is intended. * @param deadline The deadline for swapping in the destination AMM market. 0 if no * swap is intended. * @param relayer The address of the relayer at the destination. * @param relayerFee The amount distributed to the relayer at the destination. This is subtracted from the `amount`. */ function sendToL2( uint256 chainId, address recipient, uint256 amount, uint256 amountOutMin, uint256 deadline, address relayer, uint256 relayerFee ) external payable { IMessengerWrapper messengerWrapper = crossDomainMessengerWrappers[chainId]; require(messengerWrapper != IMessengerWrapper(0), "L1_BRG: chainId not supported"); require(isChainIdPaused[chainId] == false, "L1_BRG: Sends to this chainId are paused"); require(amount > 0, "L1_BRG: Must transfer a non-zero amount"); require(amount >= relayerFee, "L1_BRG: Relayer fee cannot exceed amount"); _transferToBridge(msg.sender, amount); bytes memory message = abi.encodeWithSignature( "distribute(address,uint256,uint256,uint256,address,uint256)", recipient, amount, amountOutMin, deadline, relayer, relayerFee ); chainBalance[chainId] = chainBalance[chainId].add(amount); messengerWrapper.sendCrossDomainMessage(message); emit TransferSentToL2( chainId, recipient, amount, amountOutMin, deadline, relayer, relayerFee ); } /* ========== TransferRoot Functions ========== */ /** * @dev Setting a TransferRoot is a two step process. * @dev 1. The TransferRoot is bonded with `bondTransferRoot`. Withdrawals can now begin on L1 * @dev and recipient L2's * @dev 2. The TransferRoot is confirmed after `confirmTransferRoot` is called by the l2 bridge * @dev where the TransferRoot originated. */ /** * @dev Used by the Bonder to bond a TransferRoot and propagate it up to destination L2s * @param rootHash The Merkle root of the TransferRoot Merkle tree * @param destinationChainId The id of the destination chain * @param totalAmount The amount destined for the destination chain */ function bondTransferRoot( bytes32 rootHash, uint256 destinationChainId, uint256 totalAmount ) external onlyBonder requirePositiveBalance { bytes32 transferRootId = getTransferRootId(rootHash, totalAmount); require(transferRootCommittedAt[destinationChainId][transferRootId] == 0, "L1_BRG: TransferRoot has already been confirmed"); require(transferBonds[transferRootId].createdAt == 0, "L1_BRG: TransferRoot has already been bonded"); uint256 currentTimeSlot = getTimeSlot(block.timestamp); uint256 bondAmount = getBondForTransferAmount(totalAmount); timeSlotToAmountBonded[currentTimeSlot][msg.sender] = timeSlotToAmountBonded[currentTimeSlot][msg.sender].add(bondAmount); transferBonds[transferRootId] = TransferBond( msg.sender, block.timestamp, totalAmount, uint256(0), address(0), false ); _distributeTransferRoot(rootHash, destinationChainId, totalAmount); emit TransferRootBonded(rootHash, totalAmount); } /** * @dev Used by an L2 bridge to confirm a TransferRoot via cross-domain message. Once a TransferRoot * has been confirmed, any challenge against that TransferRoot can be resolved as unsuccessful. * @param originChainId The id of the origin chain * @param rootHash The Merkle root of the TransferRoot Merkle tree * @param destinationChainId The id of the destination chain * @param totalAmount The amount destined for each destination chain * @param rootCommittedAt The block timestamp when the TransferRoot was committed on its origin chain */ function confirmTransferRoot( uint256 originChainId, bytes32 rootHash, uint256 destinationChainId, uint256 totalAmount, uint256 rootCommittedAt ) external onlyL2Bridge(originChainId) { bytes32 transferRootId = getTransferRootId(rootHash, totalAmount); require(transferRootCommittedAt[destinationChainId][transferRootId] == 0, "L1_BRG: TransferRoot already confirmed"); require(rootCommittedAt > 0, "L1_BRG: rootCommittedAt must be greater than 0"); transferRootCommittedAt[destinationChainId][transferRootId] = rootCommittedAt; chainBalance[originChainId] = chainBalance[originChainId].sub(totalAmount, "L1_BRG: Amount exceeds chainBalance. This indicates a layer-2 failure."); // If the TransferRoot was never bonded, distribute the TransferRoot. TransferBond storage transferBond = transferBonds[transferRootId]; if (transferBond.createdAt == 0) { _distributeTransferRoot(rootHash, destinationChainId, totalAmount); } emit TransferRootConfirmed(originChainId, destinationChainId, rootHash, totalAmount); } function _distributeTransferRoot( bytes32 rootHash, uint256 chainId, uint256 totalAmount ) internal { // Set TransferRoot on recipient Bridge if (chainId == getChainId()) { // Set L1 TransferRoot _setTransferRoot(rootHash, totalAmount); } else { chainBalance[chainId] = chainBalance[chainId].add(totalAmount); IMessengerWrapper messengerWrapper = crossDomainMessengerWrappers[chainId]; require(messengerWrapper != IMessengerWrapper(0), "L1_BRG: chainId not supported"); // Set L2 TransferRoot bytes memory setTransferRootMessage = abi.encodeWithSignature( "setTransferRoot(bytes32,uint256)", rootHash, totalAmount ); messengerWrapper.sendCrossDomainMessage(setTransferRootMessage); } } /* ========== External TransferRoot Challenges ========== */ /** * @dev Challenge a TransferRoot believed to be fraudulent * @param rootHash The Merkle root of the TransferRoot Merkle tree * @param originalAmount The total amount bonded for this TransferRoot * @param destinationChainId The id of the destination chain */ function challengeTransferBond(bytes32 rootHash, uint256 originalAmount, uint256 destinationChainId) external payable { bytes32 transferRootId = getTransferRootId(rootHash, originalAmount); TransferBond storage transferBond = transferBonds[transferRootId]; require(transferRootCommittedAt[destinationChainId][transferRootId] == 0, "L1_BRG: TransferRoot has already been confirmed"); require(transferBond.createdAt != 0, "L1_BRG: TransferRoot has not been bonded"); uint256 challengePeriodEnd = transferBond.createdAt.add(challengePeriod); require(challengePeriodEnd >= block.timestamp, "L1_BRG: TransferRoot cannot be challenged after challenge period"); require(transferBond.challengeStartTime == 0, "L1_BRG: TransferRoot already challenged"); transferBond.challengeStartTime = block.timestamp; transferBond.challenger = msg.sender; // Move amount from timeSlotToAmountBonded to debit uint256 timeSlot = getTimeSlot(transferBond.createdAt); uint256 bondAmount = getBondForTransferAmount(originalAmount); address bonder = transferBond.bonder; timeSlotToAmountBonded[timeSlot][bonder] = timeSlotToAmountBonded[timeSlot][bonder].sub(bondAmount); _addDebit(transferBond.bonder, bondAmount); // Get stake for challenge uint256 challengeStakeAmount = getChallengeAmountForTransferAmount(originalAmount); _transferToBridge(msg.sender, challengeStakeAmount); emit TransferBondChallenged(transferRootId, rootHash, originalAmount); } /** * @dev Resolve a challenge after the `challengeResolutionPeriod` has passed * @param rootHash The Merkle root of the TransferRoot Merkle tree * @param originalAmount The total amount originally bonded for this TransferRoot * @param destinationChainId The id of the destination chain */ function resolveChallenge(bytes32 rootHash, uint256 originalAmount, uint256 destinationChainId) external { bytes32 transferRootId = getTransferRootId(rootHash, originalAmount); TransferBond storage transferBond = transferBonds[transferRootId]; require(transferBond.challengeStartTime != 0, "L1_BRG: TransferRoot has not been challenged"); require(block.timestamp > transferBond.challengeStartTime.add(challengeResolutionPeriod), "L1_BRG: Challenge period has not ended"); require(transferBond.challengeResolved == false, "L1_BRG: TransferRoot already resolved"); transferBond.challengeResolved = true; uint256 challengeStakeAmount = getChallengeAmountForTransferAmount(originalAmount); if (transferRootCommittedAt[destinationChainId][transferRootId] > 0) { // Invalid challenge if (transferBond.createdAt > transferRootCommittedAt[destinationChainId][transferRootId].add(minTransferRootBondDelay)) { // Credit the bonder back with the bond amount plus the challenger's stake _addCredit(transferBond.bonder, getBondForTransferAmount(originalAmount).add(challengeStakeAmount)); } else { // If the TransferRoot was bonded before it was committed, the challenger and Bonder // get their stake back. This discourages Bonders from tricking challengers into // challenging a valid TransferRoots that haven't yet been committed. It also ensures // that Bonders are not punished if a TransferRoot is bonded too soon in error. // Return the challenger's stake _addCredit(transferBond.challenger, challengeStakeAmount); // Credit the bonder back with the bond amount _addCredit(transferBond.bonder, getBondForTransferAmount(originalAmount)); } } else { // Valid challenge // Burn 25% of the challengers stake _transferFromBridge(address(0xdead), challengeStakeAmount.mul(1).div(4)); // Reward challenger with the remaining 75% of their stake plus 100% of the Bonder's stake _addCredit(transferBond.challenger, challengeStakeAmount.mul(7).div(4)); } emit ChallengeResolved(transferRootId, rootHash, originalAmount); } /* ========== Override Functions ========== */ function _additionalDebit(address bonder) internal view override returns (uint256) { uint256 currentTimeSlot = getTimeSlot(block.timestamp); uint256 bonded = 0; uint256 numTimeSlots = challengePeriod / TIME_SLOT_SIZE; for (uint256 i = 0; i < numTimeSlots; i++) { bonded = bonded.add(timeSlotToAmountBonded[currentTimeSlot - i][bonder]); } return bonded; } function _requireIsGovernance() internal override { require(governance == msg.sender, "L1_BRG: Caller is not the owner"); } /* ========== External Config Management Setters ========== */ function setGovernance(address _newGovernance) external onlyGovernance { require(_newGovernance != address(0), "L1_BRG: _newGovernance cannot be address(0)"); governance = _newGovernance; } function setCrossDomainMessengerWrapper(uint256 chainId, IMessengerWrapper _crossDomainMessengerWrapper) external onlyGovernance { crossDomainMessengerWrappers[chainId] = _crossDomainMessengerWrapper; } function setChainIdDepositsPaused(uint256 chainId, bool isPaused) external onlyGovernance { isChainIdPaused[chainId] = isPaused; } function setChallengePeriod(uint256 _challengePeriod) external onlyGovernance { require(_challengePeriod % TIME_SLOT_SIZE == 0, "L1_BRG: challengePeriod must be divisible by TIME_SLOT_SIZE"); challengePeriod = _challengePeriod; } function setChallengeResolutionPeriod(uint256 _challengeResolutionPeriod) external onlyGovernance { challengeResolutionPeriod = _challengeResolutionPeriod; } function setMinTransferRootBondDelay(uint256 _minTransferRootBondDelay) external onlyGovernance { minTransferRootBondDelay = _minTransferRootBondDelay; } /* ========== Public Getters ========== */ function getBondForTransferAmount(uint256 amount) public pure returns (uint256) { // Bond covers amount plus a bounty to pay a potential challenger return amount.add(getChallengeAmountForTransferAmount(amount)); } function getChallengeAmountForTransferAmount(uint256 amount) public pure returns (uint256) { // Bond covers amount plus a bounty to pay a potential challenger return amount.div(CHALLENGE_AMOUNT_DIVISOR); } function getTimeSlot(uint256 time) public pure returns (uint256) { return time / TIME_SLOT_SIZE; } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import "./Accounting.sol"; import "../libraries/Lib_MerkleTree.sol"; /** * @dev Bridge extends the accounting system and encapsulates the logic that is shared by both the * L1 and L2 Bridges. It allows to TransferRoots to be set by parent contracts and for those * TransferRoots to be withdrawn against. It also allows the bonder to bond and withdraw Transfers * directly through `bondWithdrawal` and then settle those bonds against their TransferRoot once it * has been set. */ abstract contract Bridge is Accounting { using Lib_MerkleTree for bytes32; struct TransferRoot { uint256 total; uint256 amountWithdrawn; uint256 createdAt; } /* ========== Events ========== */ event Withdrew( bytes32 indexed transferId, address indexed recipient, uint256 amount, bytes32 transferNonce ); event WithdrawalBonded( bytes32 indexed transferId, uint256 amount ); event WithdrawalBondSettled( address indexed bonder, bytes32 indexed transferId, bytes32 indexed rootHash ); event MultipleWithdrawalsSettled( address indexed bonder, bytes32 indexed rootHash, uint256 totalBondsSettled ); event TransferRootSet( bytes32 indexed rootHash, uint256 totalAmount ); /* ========== State ========== */ mapping(bytes32 => TransferRoot) private _transferRoots; mapping(bytes32 => bool) private _spentTransferIds; mapping(address => mapping(bytes32 => uint256)) private _bondedWithdrawalAmounts; uint256 constant RESCUE_DELAY = 8 weeks; constructor(address[] memory bonders) public Accounting(bonders) {} /* ========== Public Getters ========== */ /** * @dev Get the hash that represents an individual Transfer. * @param chainId The id of the destination chain * @param recipient The address receiving the Transfer * @param amount The amount being transferred including the `_bonderFee` * @param transferNonce Used to avoid transferId collisions * @param bonderFee The amount paid to the address that withdraws the Transfer * @param amountOutMin The minimum amount received after attempting to swap in the destination * AMM market. 0 if no swap is intended. * @param deadline The deadline for swapping in the destination AMM market. 0 if no * swap is intended. */ function getTransferId( uint256 chainId, address recipient, uint256 amount, bytes32 transferNonce, uint256 bonderFee, uint256 amountOutMin, uint256 deadline ) public pure returns (bytes32) { return keccak256(abi.encode( chainId, recipient, amount, transferNonce, bonderFee, amountOutMin, deadline )); } /** * @notice getChainId can be overridden by subclasses if needed for compatibility or testing purposes. * @dev Get the current chainId * @return chainId The current chainId */ function getChainId() public virtual view returns (uint256 chainId) { this; // Silence state mutability warning without generating any additional byte code assembly { chainId := chainid() } } /** * @dev Get the TransferRoot id for a given rootHash and totalAmount * @param rootHash The Merkle root of the TransferRoot * @param totalAmount The total of all Transfers in the TransferRoot * @return The calculated transferRootId */ function getTransferRootId(bytes32 rootHash, uint256 totalAmount) public pure returns (bytes32) { return keccak256(abi.encodePacked(rootHash, totalAmount)); } /** * @dev Get the TransferRoot for a given rootHash and totalAmount * @param rootHash The Merkle root of the TransferRoot * @param totalAmount The total of all Transfers in the TransferRoot * @return The TransferRoot with the calculated transferRootId */ function getTransferRoot(bytes32 rootHash, uint256 totalAmount) public view returns (TransferRoot memory) { return _transferRoots[getTransferRootId(rootHash, totalAmount)]; } /** * @dev Get the amount bonded for the withdrawal of a transfer * @param bonder The Bonder of the withdrawal * @param transferId The Transfer's unique identifier * @return The amount bonded for a Transfer withdrawal */ function getBondedWithdrawalAmount(address bonder, bytes32 transferId) external view returns (uint256) { return _bondedWithdrawalAmounts[bonder][transferId]; } /** * @dev Get the spent status of a transfer ID * @param transferId The transfer's unique identifier * @return True if the transferId has been spent */ function isTransferIdSpent(bytes32 transferId) external view returns (bool) { return _spentTransferIds[transferId]; } /* ========== User/Relayer External Functions ========== */ /** * @notice Can be called by anyone (recipient or relayer) * @dev Withdraw a Transfer from its destination bridge * @param recipient The address receiving the Transfer * @param amount The amount being transferred including the `_bonderFee` * @param transferNonce Used to avoid transferId collisions * @param bonderFee The amount paid to the address that withdraws the Transfer * @param amountOutMin The minimum amount received after attempting to swap in the destination * AMM market. 0 if no swap is intended. (only used to calculate `transferId` in this function) * @param deadline The deadline for swapping in the destination AMM market. 0 if no * swap is intended. (only used to calculate `transferId` in this function) * @param rootHash The Merkle root of the TransferRoot * @param transferRootTotalAmount The total amount being transferred in a TransferRoot * @param transferIdTreeIndex The index of the transferId in the Merkle tree * @param siblings The siblings of the transferId in the Merkle tree * @param totalLeaves The total number of leaves in the Merkle tree */ function withdraw( address recipient, uint256 amount, bytes32 transferNonce, uint256 bonderFee, uint256 amountOutMin, uint256 deadline, bytes32 rootHash, uint256 transferRootTotalAmount, uint256 transferIdTreeIndex, bytes32[] calldata siblings, uint256 totalLeaves ) external nonReentrant { bytes32 transferId = getTransferId( getChainId(), recipient, amount, transferNonce, bonderFee, amountOutMin, deadline ); require( rootHash.verify( transferId, transferIdTreeIndex, siblings, totalLeaves ) , "BRG: Invalid transfer proof"); bytes32 transferRootId = getTransferRootId(rootHash, transferRootTotalAmount); _addToAmountWithdrawn(transferRootId, amount); _fulfillWithdraw(transferId, recipient, amount, uint256(0)); emit Withdrew(transferId, recipient, amount, transferNonce); } /** * @dev Allows the bonder to bond individual withdrawals before their TransferRoot has been committed. * @param recipient The address receiving the Transfer * @param amount The amount being transferred including the `_bonderFee` * @param transferNonce Used to avoid transferId collisions * @param bonderFee The amount paid to the address that withdraws the Transfer */ function bondWithdrawal( address recipient, uint256 amount, bytes32 transferNonce, uint256 bonderFee ) external onlyBonder requirePositiveBalance nonReentrant { bytes32 transferId = getTransferId( getChainId(), recipient, amount, transferNonce, bonderFee, 0, 0 ); _bondWithdrawal(transferId, amount); _fulfillWithdraw(transferId, recipient, amount, bonderFee); } /** * @dev Refunds the Bonder's stake from a bonded withdrawal and counts that withdrawal against * its TransferRoot. * @param bonder The Bonder of the withdrawal * @param transferId The Transfer's unique identifier * @param rootHash The Merkle root of the TransferRoot * @param transferRootTotalAmount The total amount being transferred in a TransferRoot * @param transferIdTreeIndex The index of the transferId in the Merkle tree * @param siblings The siblings of the transferId in the Merkle tree * @param totalLeaves The total number of leaves in the Merkle tree */ function settleBondedWithdrawal( address bonder, bytes32 transferId, bytes32 rootHash, uint256 transferRootTotalAmount, uint256 transferIdTreeIndex, bytes32[] calldata siblings, uint256 totalLeaves ) external { require( rootHash.verify( transferId, transferIdTreeIndex, siblings, totalLeaves ) , "BRG: Invalid transfer proof"); bytes32 transferRootId = getTransferRootId(rootHash, transferRootTotalAmount); uint256 amount = _bondedWithdrawalAmounts[bonder][transferId]; require(amount > 0, "L2_BRG: transferId has no bond"); _bondedWithdrawalAmounts[bonder][transferId] = 0; _addToAmountWithdrawn(transferRootId, amount); _addCredit(bonder, amount); emit WithdrawalBondSettled(bonder, transferId, rootHash); } /** * @dev Refunds the Bonder for all withdrawals that they bonded in a TransferRoot. * @param bonder The address of the Bonder being refunded * @param transferIds All transferIds in the TransferRoot in order * @param totalAmount The totalAmount of the TransferRoot */ function settleBondedWithdrawals( address bonder, // transferIds _must_ be calldata or it will be mutated by Lib_MerkleTree.getMerkleRoot bytes32[] calldata transferIds, uint256 totalAmount ) external { bytes32 rootHash = Lib_MerkleTree.getMerkleRoot(transferIds); bytes32 transferRootId = getTransferRootId(rootHash, totalAmount); uint256 totalBondsSettled = 0; for(uint256 i = 0; i < transferIds.length; i++) { uint256 transferBondAmount = _bondedWithdrawalAmounts[bonder][transferIds[i]]; if (transferBondAmount > 0) { totalBondsSettled = totalBondsSettled.add(transferBondAmount); _bondedWithdrawalAmounts[bonder][transferIds[i]] = 0; } } _addToAmountWithdrawn(transferRootId, totalBondsSettled); _addCredit(bonder, totalBondsSettled); emit MultipleWithdrawalsSettled(bonder, rootHash, totalBondsSettled); } /* ========== External TransferRoot Rescue ========== */ /** * @dev Allows governance to withdraw the remaining amount from a TransferRoot after the rescue delay has passed. * @param rootHash the Merkle root of the TransferRoot * @param originalAmount The TransferRoot's recorded total * @param recipient The address receiving the remaining balance */ function rescueTransferRoot(bytes32 rootHash, uint256 originalAmount, address recipient) external onlyGovernance { bytes32 transferRootId = getTransferRootId(rootHash, originalAmount); TransferRoot memory transferRoot = getTransferRoot(rootHash, originalAmount); require(transferRoot.createdAt != 0, "BRG: TransferRoot not found"); assert(transferRoot.total == originalAmount); uint256 rescueDelayEnd = transferRoot.createdAt.add(RESCUE_DELAY); require(block.timestamp >= rescueDelayEnd, "BRG: TransferRoot cannot be rescued before the Rescue Delay"); uint256 remainingAmount = transferRoot.total.sub(transferRoot.amountWithdrawn); _addToAmountWithdrawn(transferRootId, remainingAmount); _transferFromBridge(recipient, remainingAmount); } /* ========== Internal Functions ========== */ function _markTransferSpent(bytes32 transferId) internal { require(!_spentTransferIds[transferId], "BRG: The transfer has already been withdrawn"); _spentTransferIds[transferId] = true; } function _addToAmountWithdrawn(bytes32 transferRootId, uint256 amount) internal { TransferRoot storage transferRoot = _transferRoots[transferRootId]; require(transferRoot.total > 0, "BRG: Transfer root not found"); uint256 newAmountWithdrawn = transferRoot.amountWithdrawn.add(amount); require(newAmountWithdrawn <= transferRoot.total, "BRG: Withdrawal exceeds TransferRoot total"); transferRoot.amountWithdrawn = newAmountWithdrawn; } function _setTransferRoot(bytes32 rootHash, uint256 totalAmount) internal { bytes32 transferRootId = getTransferRootId(rootHash, totalAmount); require(_transferRoots[transferRootId].total == 0, "BRG: Transfer root already set"); require(totalAmount > 0, "BRG: Cannot set TransferRoot totalAmount of 0"); _transferRoots[transferRootId] = TransferRoot(totalAmount, 0, block.timestamp); emit TransferRootSet(rootHash, totalAmount); } function _bondWithdrawal(bytes32 transferId, uint256 amount) internal { require(_bondedWithdrawalAmounts[msg.sender][transferId] == 0, "BRG: Withdrawal has already been bonded"); _addDebit(msg.sender, amount); _bondedWithdrawalAmounts[msg.sender][transferId] = amount; emit WithdrawalBonded(transferId, amount); } /* ========== Private Functions ========== */ /// @dev Completes the Transfer, distributes the Bonder fee and marks the Transfer as spent. function _fulfillWithdraw( bytes32 transferId, address recipient, uint256 amount, uint256 bonderFee ) private { _markTransferSpent(transferId); _transferFromBridge(recipient, amount.sub(bonderFee)); if (bonderFee > 0) { _transferFromBridge(msg.sender, bonderFee); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.12 <0.8.0; pragma experimental ABIEncoderV2; interface IMessengerWrapper { function sendCrossDomainMessage(bytes memory _calldata) external; function verifySender(address l1BridgeCaller, bytes memory _data) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; /** * @dev Accounting is an abstract contract that encapsulates the most critical logic in the Hop contracts. * The accounting system works by using two balances that can only increase `_credit` and `_debit`. * A bonder's available balance is the total credit minus the total debit. The contract exposes * two external functions that allows a bonder to stake and unstake and exposes two internal * functions to its child contracts that allow the child contract to add to the credit * and debit balance. In addition, child contracts can override `_additionalDebit` to account * for any additional debit balance in an alternative way. Lastly, it exposes a modifier, * `requirePositiveBalance`, that can be used by child contracts to ensure the bonder does not * use more than its available stake. */ abstract contract Accounting is ReentrancyGuard { using SafeMath for uint256; mapping(address => bool) private _isBonder; mapping(address => uint256) private _credit; mapping(address => uint256) private _debit; event Stake ( address indexed account, uint256 amount ); event Unstake ( address indexed account, uint256 amount ); event BonderAdded ( address indexed newBonder ); event BonderRemoved ( address indexed previousBonder ); /* ========== Modifiers ========== */ modifier onlyBonder { require(_isBonder[msg.sender], "ACT: Caller is not bonder"); _; } modifier onlyGovernance { _requireIsGovernance(); _; } /// @dev Used by parent contract to ensure that the Bonder is solvent at the end of the transaction. modifier requirePositiveBalance { _; require(getCredit(msg.sender) >= getDebitAndAdditionalDebit(msg.sender), "ACT: Not enough available credit"); } /// @dev Sets the Bonder addresses constructor(address[] memory bonders) public { for (uint256 i = 0; i < bonders.length; i++) { require(_isBonder[bonders[i]] == false, "ACT: Cannot add duplicate bonder"); _isBonder[bonders[i]] = true; emit BonderAdded(bonders[i]); } } /* ========== Virtual functions ========== */ /** * @dev The following functions are overridden in L1_Bridge and L2_Bridge */ function _transferFromBridge(address recipient, uint256 amount) internal virtual; function _transferToBridge(address from, uint256 amount) internal virtual; function _requireIsGovernance() internal virtual; /** * @dev This function can be optionally overridden by a parent contract to track any additional * debit balance in an alternative way. */ function _additionalDebit(address /*bonder*/) internal view virtual returns (uint256) { this; // Silence state mutability warning without generating any additional byte code return 0; } /* ========== Public/external getters ========== */ /** * @dev Check if address is a Bonder * @param maybeBonder The address being checked * @return true if address is a Bonder */ function getIsBonder(address maybeBonder) public view returns (bool) { return _isBonder[maybeBonder]; } /** * @dev Get the Bonder's credit balance * @param bonder The owner of the credit balance being checked * @return The credit balance for the Bonder */ function getCredit(address bonder) public view returns (uint256) { return _credit[bonder]; } /** * @dev Gets the debit balance tracked by `_debit` and does not include `_additionalDebit()` * @param bonder The owner of the debit balance being checked * @return The debit amount for the Bonder */ function getRawDebit(address bonder) external view returns (uint256) { return _debit[bonder]; } /** * @dev Get the Bonder's total debit * @param bonder The owner of the debit balance being checked * @return The Bonder's total debit balance */ function getDebitAndAdditionalDebit(address bonder) public view returns (uint256) { return _debit[bonder].add(_additionalDebit(bonder)); } /* ========== Bonder external functions ========== */ /** * @dev Allows the Bonder to deposit tokens and increase its credit balance * @param bonder The address being staked on * @param amount The amount being staked */ function stake(address bonder, uint256 amount) external payable nonReentrant { require(_isBonder[bonder] == true, "ACT: Address is not bonder"); _transferToBridge(msg.sender, amount); _addCredit(bonder, amount); emit Stake(bonder, amount); } /** * @dev Allows the caller to withdraw any available balance and add to their debit balance * @param amount The amount being unstaked */ function unstake(uint256 amount) external requirePositiveBalance nonReentrant { _addDebit(msg.sender, amount); _transferFromBridge(msg.sender, amount); emit Unstake(msg.sender, amount); } /** * @dev Add Bonder to allowlist * @param bonder The address being added as a Bonder */ function addBonder(address bonder) external onlyGovernance { require(_isBonder[bonder] == false, "ACT: Address is already bonder"); _isBonder[bonder] = true; emit BonderAdded(bonder); } /** * @dev Remove Bonder from allowlist * @param bonder The address being removed as a Bonder */ function removeBonder(address bonder) external onlyGovernance { require(_isBonder[bonder] == true, "ACT: Address is not bonder"); _isBonder[bonder] = false; emit BonderRemoved(bonder); } /* ========== Internal functions ========== */ function _addCredit(address bonder, uint256 amount) internal { _credit[bonder] = _credit[bonder].add(amount); } function _addDebit(address bonder, uint256 amount) internal { _debit[bonder] = _debit[bonder].add(amount); } }
// SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.8.0; /** * @title Lib_MerkleTree * @author River Keefer */ library Lib_MerkleTree { /********************** * Internal Functions * **********************/ /** * Calculates a merkle root for a list of 32-byte leaf hashes. WARNING: If the number * of leaves passed in is not a power of two, it pads out the tree with zero hashes. * If you do not know the original length of elements for the tree you are verifying, * then this may allow empty leaves past _elements.length to pass a verification check down the line. * Note that the _elements argument is modified, therefore it must not be used again afterwards * @param _elements Array of hashes from which to generate a merkle root. * @return Merkle root of the leaves, with zero hashes for non-powers-of-two (see above). */ function getMerkleRoot( bytes32[] memory _elements ) internal pure returns ( bytes32 ) { require( _elements.length > 0, "Lib_MerkleTree: Must provide at least one leaf hash." ); if (_elements.length == 1) { return _elements[0]; } uint256[16] memory defaults = [ 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563, 0x633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d, 0x890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d, 0x3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8, 0xecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da, 0xdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5, 0x617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7, 0x292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead, 0xe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e10, 0x7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f82, 0xe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e83636516, 0x3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c, 0xad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e, 0xa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab, 0x4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c862, 0x2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf10 ]; // Reserve memory space for our hashes. bytes memory buf = new bytes(64); // We'll need to keep track of left and right siblings. bytes32 leftSibling; bytes32 rightSibling; // Number of non-empty nodes at the current depth. uint256 rowSize = _elements.length; // Current depth, counting from 0 at the leaves uint256 depth = 0; // Common sub-expressions uint256 halfRowSize; // rowSize / 2 bool rowSizeIsOdd; // rowSize % 2 == 1 while (rowSize > 1) { halfRowSize = rowSize / 2; rowSizeIsOdd = rowSize % 2 == 1; for (uint256 i = 0; i < halfRowSize; i++) { leftSibling = _elements[(2 * i) ]; rightSibling = _elements[(2 * i) + 1]; assembly { mstore(add(buf, 32), leftSibling ) mstore(add(buf, 64), rightSibling) } _elements[i] = keccak256(buf); } if (rowSizeIsOdd) { leftSibling = _elements[rowSize - 1]; rightSibling = bytes32(defaults[depth]); assembly { mstore(add(buf, 32), leftSibling) mstore(add(buf, 64), rightSibling) } _elements[halfRowSize] = keccak256(buf); } rowSize = halfRowSize + (rowSizeIsOdd ? 1 : 0); depth++; } return _elements[0]; } /** * Verifies a merkle branch for the given leaf hash. Assumes the original length * of leaves generated is a known, correct input, and does not return true for indices * extending past that index (even if _siblings would be otherwise valid.) * @param _root The Merkle root to verify against. * @param _leaf The leaf hash to verify inclusion of. * @param _index The index in the tree of this leaf. * @param _siblings Array of sibline nodes in the inclusion proof, starting from depth 0 (bottom of the tree). * @param _totalLeaves The total number of leaves originally passed into. * @return Whether or not the merkle branch and leaf passes verification. */ function verify( bytes32 _root, bytes32 _leaf, uint256 _index, bytes32[] memory _siblings, uint256 _totalLeaves ) internal pure returns ( bool ) { require( _totalLeaves > 0, "Lib_MerkleTree: Total leaves must be greater than zero." ); require( _index < _totalLeaves, "Lib_MerkleTree: Index out of bounds." ); require( _siblings.length == _ceilLog2(_totalLeaves), "Lib_MerkleTree: Total siblings does not correctly correspond to total leaves." ); bytes32 computedRoot = _leaf; for (uint256 i = 0; i < _siblings.length; i++) { if ((_index & 1) == 1) { computedRoot = keccak256( abi.encodePacked( _siblings[i], computedRoot ) ); } else { computedRoot = keccak256( abi.encodePacked( computedRoot, _siblings[i] ) ); } _index >>= 1; } return _root == computedRoot; } /********************* * Private Functions * *********************/ /** * Calculates the integer ceiling of the log base 2 of an input. * @param _in Unsigned input to calculate the log. * @return ceil(log_base_2(_in)) */ function _ceilLog2( uint256 _in ) private pure returns ( uint256 ) { require( _in > 0, "Lib_MerkleTree: Cannot compute ceil(log_2) of 0." ); if (_in == 1) { return 0; } // Find the highest set bit (will be floor(log_2)). // Borrowed with <3 from https://github.com/ethereum/solidity-examples uint256 val = _in; uint256 highest = 0; for (uint256 i = 128; i >= 1; i >>= 1) { if (val & (uint(1) << i) - 1 << i != 0) { highest += i; val >>= i; } } // Increment by one if this is not a perfect logarithm. if ((uint(1) << highest) != _in) { highest += 1; } return highest; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
{ "optimizer": { "enabled": true, "runs": 50000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
[{"inputs":[{"internalType":"address[]","name":"bonders","type":"address[]"},{"internalType":"address","name":"_governance","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newBonder","type":"address"}],"name":"BonderAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousBonder","type":"address"}],"name":"BonderRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferRootId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"originalAmount","type":"uint256"}],"name":"ChallengeResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bonder","type":"address"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"totalBondsSettled","type":"uint256"}],"name":"MultipleWithdrawalsSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferRootId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"originalAmount","type":"uint256"}],"name":"TransferBondChallenged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferRootBonded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"TransferRootConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"TransferRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"},{"indexed":true,"internalType":"address","name":"relayer","type":"address"},{"indexed":false,"internalType":"uint256","name":"relayerFee","type":"uint256"}],"name":"TransferSentToL2","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bonder","type":"address"},{"indexed":true,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"}],"name":"WithdrawalBondSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawalBonded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"transferNonce","type":"bytes32"}],"name":"Withdrew","type":"event"},{"inputs":[],"name":"CHALLENGE_AMOUNT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIME_SLOT_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"addBonder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"bondTransferRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"transferNonce","type":"bytes32"},{"internalType":"uint256","name":"bonderFee","type":"uint256"}],"name":"bondWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"chainBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengeResolutionPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"originalAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"}],"name":"challengeTransferBond","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"rootCommittedAt","type":"uint256"}],"name":"confirmTransferRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"crossDomainMessengerWrappers","outputs":[{"internalType":"contract IMessengerWrapper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBondForTransferAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"bytes32","name":"transferId","type":"bytes32"}],"name":"getBondedWithdrawalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getChallengeAmountForTransferAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"getCredit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"getDebitAndAdditionalDebit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"maybeBonder","type":"address"}],"name":"getIsBonder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"getRawDebit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"getTimeSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"transferNonce","type":"bytes32"},{"internalType":"uint256","name":"bonderFee","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"getTransferId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"getTransferRoot","outputs":[{"components":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"amountWithdrawn","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct Bridge.TransferRoot","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"getTransferRootId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isChainIdPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"transferId","type":"bytes32"}],"name":"isTransferIdSpent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTransferRootBondDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"removeBonder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"originalAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueTransferRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"originalAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"}],"name":"resolveChallenge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint256","name":"relayerFee","type":"uint256"}],"name":"sendToL2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"isPaused","type":"bool"}],"name":"setChainIdDepositsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_challengePeriod","type":"uint256"}],"name":"setChallengePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_challengeResolutionPeriod","type":"uint256"}],"name":"setChallengeResolutionPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"contract IMessengerWrapper","name":"_crossDomainMessengerWrapper","type":"address"}],"name":"setCrossDomainMessengerWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernance","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minTransferRootBondDelay","type":"uint256"}],"name":"setMinTransferRootBondDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"bytes32","name":"transferId","type":"bytes32"},{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"transferRootTotalAmount","type":"uint256"},{"internalType":"uint256","name":"transferIdTreeIndex","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"},{"internalType":"uint256","name":"totalLeaves","type":"uint256"}],"name":"settleBondedWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"bytes32[]","name":"transferIds","type":"bytes32[]"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"settleBondedWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"timeSlotToAmountBonded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"transferBonds","outputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"challengeStartTime","type":"uint256"},{"internalType":"address","name":"challenger","type":"address"},{"internalType":"bool","name":"challengeResolved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"transferRootCommittedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"transferNonce","type":"bytes32"},{"internalType":"uint256","name":"bonderFee","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"transferRootTotalAmount","type":"uint256"},{"internalType":"uint256","name":"transferIdTreeIndex","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"},{"internalType":"uint256","name":"totalLeaves","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405262015180600e55620d2f00600f556103846010553480156200002557600080fd5b5060405162004af838038062004af88339810160408190526200004891620001b2565b81818180600160008190555060005b81518110156200016657600160008383815181106200007257fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615620000c25760405162461bcd60e51b8152600401620000b9906200027d565b60405180910390fd5b6001806000848481518110620000d457fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508181815181106200012057fe5b60200260200101516001600160a01b03167f2cec73b7434d3b91198ad1a618f63e6a0761ce281af5ec9ec76606d948d03e2360405160405180910390a260010162000057565b5050600b80546001600160a01b0319166001600160a01b03939093169290921790915550620002d992505050565b80516001600160a01b0381168114620001ac57600080fd5b92915050565b60008060408385031215620001c5578182fd5b82516001600160401b0380821115620001dc578384fd5b818501915085601f830112620001f0578384fd5b815181811115620001ff578485fd5b6020915081810262000213838201620002b2565b8281528381019085850183870186018b10156200022e578889fd5b8896505b848710156200025c57620002478b8262000194565b83526001969096019591850191850162000232565b5080975050505050620002728682870162000194565b925050509250929050565b6020808252818101527f4143543a2043616e6e6f7420616464206475706c696361746520626f6e646572604082015260600190565b6040518181016001600160401b0381118282101715620002d157600080fd5b604052919050565b61480f80620002e96000396000f3fe6080604052600436106102f25760003560e01c806381707b801161018f578063cbd1642e116100e1578063eecd57e61161008a578063fa2a69a311610064578063fa2a69a314610814578063fc110b6714610834578063ffa9286c14610854576102f2565b8063eecd57e6146107bf578063ef6ebe5e146107df578063f3f480d9146107ff576102f2565b8063d5ef7551116100bb578063d5ef75511461076c578063deace8f51461078c578063e19be1501461079f576102f2565b8063cbd1642e146106ff578063ce803b4f1461071f578063d44481631461074c576102f2565b8063a35962f311610143578063af215f941161011d578063af215f941461069f578063b162717e146106bf578063c7525dd3146106df576102f2565b8063a35962f31461064c578063ab033ea91461066c578063adc9772e1461068c576102f2565b8063960a7afa11610174578063960a7afa146105f757806398c4f76d14610617578063a239f5ee1461062c576102f2565b806381707b80146105b75780638d8798bf146105d7576102f2565b80633a7af631116102485780635a7e1083116101fc5780636cff06a7116101d65780636cff06a71461056d5780637398d28214610582578063767631d5146105a2576102f2565b80635a7e1083146104f95780635aa6e6751461052b5780635d475fdd1461054d576102f2565b80634de8c6e61161022d5780634de8c6e6146104a45780635325937f146104b957806357344e6f146104d9576102f2565b80633a7af631146104575780633b8fea2814610484576102f2565b806323c452cd116102aa578063302830ab11610284578063302830ab146104025780633408e4701461042257806339ada66914610437576102f2565b806323c452cd146103a25780632b85dcc9146103c25780632e17de78146103e2576102f2565b806313948c76116102db57806313948c7614610339578063149420241461036f5780631bbe15ea1461038f576102f2565b806304e6c2c0146102f75780630f7aadb714610319575b600080fd5b34801561030357600080fd5b506103176103123660046133ac565b610874565b005b34801561032557600080fd5b50610317610334366004613509565b61095e565b34801561034557600080fd5b506103596103543660046133ac565b610abf565b6040516103669190613943565b60405180910390f35b34801561037b57600080fd5b5061031761038a366004613747565b610aeb565b61031761039d36600461362d565b610b31565b3480156103ae57600080fd5b506103176103bd3660046134cf565b610d9b565b3480156103ce57600080fd5b506103596103dd3660046135bc565b610ead565b3480156103ee57600080fd5b506103176103fd3660046135bc565b610eb5565b34801561040e57600080fd5b5061035961041d366004613422565b610fab565b34801561042e57600080fd5b50610359610fe3565b34801561044357600080fd5b506103176104523660046135bc565b610fe7565b34801561046357600080fd5b506104776104723660046135bc565b610ff4565b6040516103669190613938565b34801561049057600080fd5b5061035961049f3660046135d4565b611009565b3480156104b057600080fd5b50610359611026565b3480156104c557600080fd5b506103176104d43660046133ac565b61102c565b3480156104e557600080fd5b506103596104f43660046133ac565b61110e565b34801561050557600080fd5b506105196105143660046135bc565b611136565b604051610366969594939291906138a8565b34801561053757600080fd5b5061054061119a565b604051610366919061381d565b34801561055957600080fd5b506103176105683660046135bc565b6111b6565b34801561057957600080fd5b506103596111ff565b34801561058e57600080fd5b5061035961059d366004613658565b611205565b3480156105ae57600080fd5b50610359611222565b3480156105c357600080fd5b506103176105d236600461362d565b611228565b3480156105e357600080fd5b506103176105f236600461362d565b6114dc565b34801561060357600080fd5b506103596106123660046135d4565b6117aa565b34801561062357600080fd5b506103596117dd565b34801561063857600080fd5b506103596106473660046135bc565b6117e2565b34801561065857600080fd5b506105406106673660046135bc565b6117ef565b34801561067857600080fd5b506103176106873660046133ac565b611817565b61031761069a366004613422565b6118b3565b3480156106ab57600080fd5b506103596106ba366004613687565b6119c4565b3480156106cb57600080fd5b506103176106da3660046133c8565b611a06565b3480156106eb57600080fd5b506103176106fa36600461344d565b611b83565b34801561070b57600080fd5b5061031761071a3660046135f5565b611d0a565b34801561072b57600080fd5b5061073f61073a3660046135d4565b611e01565b60405161036691906146c3565b34801561075857600080fd5b50610317610767366004613658565b611e56565b34801561077857600080fd5b506104776107873660046133ac565b611eb1565b61031761079a3660046136df565b611edc565b3480156107ab57600080fd5b506103596107ba3660046135bc565b6121b9565b3480156107cb57600080fd5b506103176107da3660046135bc565b6121ce565b3480156107eb57600080fd5b506103176107fa36600461376f565b6121db565b34801561080b57600080fd5b506103596123c4565b34801561082057600080fd5b5061047761082f3660046135bc565b6123ca565b34801561084057600080fd5b5061035961084f3660046135bc565b6123df565b34801561086057600080fd5b5061035961086f3660046133ac565b6123f1565b61087c61242b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602081905260409091205460ff161515146108ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613d0e565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660008181526001602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f4234ba611d325b3ba434c4e1b037967b955b1274d4185ee9847b7491111a48ff9190a250565b6002600054141561099b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b600260009081556109b86109ad610fe3565b8e8e8e8e8e8e6119c4565b90506109fe81868686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d95949392508891505061247e565b610a34576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061428c565b6000610a4088886117aa565b9050610a4c818e6125e8565b610a59828f8f6000612688565b8d73ffffffffffffffffffffffffffffffffffffffff16827f9475cdbde5fc71fe2ccd413c82878ee54d061b9f74f9e2e1a03ff1178821502c8f8f604051610aa29291906137f3565b60405180910390a350506001600055505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260409020545b919050565b610af361242b565b6000918252600d602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6000610b3d84846117aa565b600081815260086020908152604080832086845260078352818420858552909252909120549192509015610b9d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614109565b6001810154610bd8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613a87565b6000610bf3600e5483600101546126af90919063ffffffff16565b905042811015610c2f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906142c3565b600382015415610c6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613c54565b4260038301556004820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790556001820154600090610cae90610ead565b90506000610cbb876121b9565b8454600084815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff9094168084529390915290205491925090610cfe90836126f5565b600084815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff80871685529252909120919091558554610d3f911683612737565b6000610d4a896117e2565b9050610d563382612794565b89877fec2697dcba539a0ac947cdf1f6d0b6314c065429eca8be2435859b10209d4c278b604051610d879190613943565b60405180910390a350505050505050505050565b3360009081526001602052604090205460ff16610de4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614255565b60026000541415610e21576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b60026000908155610e3f610e33610fe3565b868686866000806119c4565b9050610e4b81856127d1565b610e5781868685612688565b506001600055610e66336123f1565b610e6f3361110e565b1015610ea7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141c3565b50505050565b613840900490565b60026000541415610ef2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b6002600055610f013382612737565b610f0b3382612888565b3373ffffffffffffffffffffffffffffffffffffffff167f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd82604051610f519190613943565b60405180910390a26001600055610f67336123f1565b610f703361110e565b1015610fa8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141c3565b50565b73ffffffffffffffffffffffffffffffffffffffff821660009081526006602090815260408083208484529091529020545b92915050565b4690565b610fef61242b565b601055565b60009081526005602052604090205460ff1690565b600760209081526000928352604080842090915290825290205481565b61384081565b61103461242b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604090205460ff1615611094576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613b52565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155517f2cec73b7434d3b91198ad1a618f63e6a0761ce281af5ec9ec76606d948d03e239190a250565b73ffffffffffffffffffffffffffffffffffffffff1660009081526002602052604090205490565b6008602052600090815260409020805460018201546002830154600384015460049094015473ffffffffffffffffffffffffffffffffffffffff93841694929391929181169074010000000000000000000000000000000000000000900460ff1686565b600b5473ffffffffffffffffffffffffffffffffffffffff1681565b6111be61242b565b6138408106156111fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906139f3565b600e55565b60105481565b600960209081526000928352604080842090915290825290205481565b600f5481565b600061123484846117aa565b6000818152600860205260409020600381015491925090611281576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061445e565b600f546003820154611292916126af565b42116112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614321565b600481015474010000000000000000000000000000000000000000900460ff1615611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613bf7565b6004810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055600061136d856117e2565b6000858152600760209081526040808320878452909152902054909150156114485760105460008581526007602090815260408083208784529091529020546113b5916126af565b826001015411156113f95781546113f49073ffffffffffffffffffffffffffffffffffffffff166113ef836113e9896121b9565b906126af565b61293c565b611443565b600482015461141e9073ffffffffffffffffffffffffffffffffffffffff168261293c565b81546114439073ffffffffffffffffffffffffffffffffffffffff166113ef876121b9565b61149b565b61146961dead611464600461145e856001612999565b906129ed565b612888565b60048083015461149b9173ffffffffffffffffffffffffffffffffffffffff909116906113ef9061145e856007612999565b85837f4a99228a8a6d774d261be57ab0ed833bb1bae1f22bbbd3d4767b75ad03fdddf7876040516114cc9190613943565b60405180910390a3505050505050565b3360009081526001602052604090205460ff16611525576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614255565b600061153184836117aa565b600084815260076020908152604080832084845290915290205490915015611585576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614109565b600081815260086020526040902060010154156115ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614609565b60006115d942610ead565b905060006115e6846121b9565b600083815260096020908152604080832033845290915290205490915061160d90826126af565b60008381526009602090815260408083203380855290835281842094909455805160c08101825293845242848301908152848201898152606086018581526080870186815260a088018781528b88526008909652939095209551865473ffffffffffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161788559251600188015590516002870155935160038601559051600490940180549251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff95909416929091169190911792909216179055611720868686612a39565b857fa57b3e1f3af9eca02201028629700658608222c365064584cfe65d9630ef4f7b856040516117509190613943565b60405180910390a2505050611764336123f1565b61176d3361110e565b10156117a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141c3565b505050565b600082826040516020016117bf9291906137f3565b60405160208183030381529060405280519060200120905092915050565b600a81565b6000610fdd82600a6129ed565b600c6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61181f61242b565b73ffffffffffffffffffffffffffffffffffffffff811661186c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061454f565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600260005414156118f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b6002600090815573ffffffffffffffffffffffffffffffffffffffff831681526001602081905260409091205460ff16151514611959576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613d0e565b6119633382612794565b61196d828261293c565b8173ffffffffffffffffffffffffffffffffffffffff167febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a826040516119b39190613943565b60405180910390a250506001600055565b6000878787878787876040516020016119e397969594939291906146e4565b604051602081830303815290604052805190602001209050979650505050505050565b6000611a44848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612bef92505050565b90506000611a5282846117aa565b90506000805b85811015611b165773ffffffffffffffffffffffffffffffffffffffff8816600090815260066020526040812081898985818110611a9257fe5b9050602002013581526020019081526020016000205490506000811115611b0d57611abd83826126af565b73ffffffffffffffffffffffffffffffffffffffff8a16600090815260066020526040812091945090818a8a86818110611af357fe5b905060200201358152602001908152602001600020819055505b50600101611a58565b50611b2182826125e8565b611b2b878261293c565b828773ffffffffffffffffffffffffffffffffffffffff167f78e830d08be9d5f957414c84d685c061ecbd8467be98b42ebb64f0118b57d2ff83604051611b729190613943565b60405180910390a350505050505050565b611bc787858585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c95949392508791505061247e565b611bfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061428c565b6000611c0987876117aa565b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526006602090815260408083208c845290915290205490915080611c74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613ae4565b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526006602090815260408083208c8452909152812055611caf82826125e8565b611cb98a8261293c565b87898b73ffffffffffffffffffffffffffffffffffffffff167f84eb21b24c31b27a3bc67dde4a598aad06db6e9415cd66544492b9616996143c60405160405180910390a450505050505050505050565b611d1261242b565b6000611d1e84846117aa565b9050611d28613323565b611d328585611e01565b9050806040015160001415611d73576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613b89565b80518414611d7d57fe5b6040810151600090611d92906249d4006126af565b905080421015611dce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613cb1565b60208201518251600091611de291906126f5565b9050611dee84826125e8565b611df88582612888565b50505050505050565b611e09613323565b60046000611e1785856117aa565b81526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905092915050565b611e5e61242b565b6000918252600c602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604090205460ff1690565b6000878152600c602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611f38576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613f84565b6000888152600d602052604090205460ff1615611f81576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613d45565b60008611611fbb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061395f565b81861015611ff5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614666565b611fff3387612794565b606087878787878760405160240161201c969594939291906138f0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcc29a3060000000000000000000000000000000000000000000000000000000017905260008c8152600a90915220549091506120ac90886126af565b60008a8152600a60205260409081902091909155517f419cb55000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063419cb5509061211090849060040161394c565b600060405180830381600087803b15801561212a57600080fd5b505af115801561213e573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a7f0a0607688c86ec1775abcdbab7b33a3a35a6c9cde677c9be880150c231cc6b0b8a8a8a896040516121a6949392919061472a565b60405180910390a4505050505050505050565b6000610fdd6121c7836117e2565b83906126af565b6121d661242b565b600f55565b6000858152600c60205260408082205490517f99178dd8000000000000000000000000000000000000000000000000000000008152879273ffffffffffffffffffffffffffffffffffffffff9092169182916399178dd89161224491339190369060040161383e565b600060405180830381600087803b15801561225e57600080fd5b505af1158015612272573d6000803e3d6000fd5b50505050600061228287866117aa565b6000878152600760209081526040808320848452909152902054909150156122d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061404f565b60008411612310576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613dd9565b600086815260076020908152604080832084845282529182902086905581516080810190925260468083526123619288929091906147949083013960008b8152600a60205260409020549190613026565b6000898152600a60209081526040808320939093558382526008905220600181015461239257612392888888612a39565b87878a7ffdfb0eefa96935b8a8c0edf528e125dc6f3934fdbbfce31b38967e8ff413dccd896040516121a69190613943565b600e5481565b600d6020526000908152604090205460ff1681565b600a6020526000908152604090205481565b6000610fdd6123ff8361306c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054906126af565b600b5473ffffffffffffffffffffffffffffffffffffffff16331461247c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613a50565b565b60008082116124b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614166565b8184106124f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613f27565b6124fb826130ea565b835114612534576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061437e565b8460005b84518110156125db5785600116600114156125905784818151811061255957fe5b6020026020010151826040516020016125739291906137f3565b6040516020818303038152906040528051906020012091506125cf565b8185828151811061259d57fe5b60200260200101516040516020016125b69291906137f3565b6040516020818303038152906040528051906020012091505b600195861c9501612538565b5090951495945050505050565b6000828152600460205260409020805461262e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613b1b565b600181015460009061264090846126af565b825490915081111561267e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906144bb565b6001909101555050565b61269184613199565b61269f8361146484846126f5565b8015610ea757610ea73382612888565b6000828201838110156126ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613bc0565b9392505050565b600082821115612731576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613da2565b50900390565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205461276790826126af565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526003602052604090209190915550565b8034146127cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613eca565b5050565b33600090815260066020908152604080832085845290915290205415612823576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614401565b61282d3382612737565b336000908152600660209081526040808320858452909152908190208290555182907f0c3d250c7831051e78aa6a56679e590374c7c424415ffe4aa474491def2fe7059061287c908490613943565b60405180910390a25050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516128bf9190613801565b60006040518083038185875af1925050503d80600081146128fc576040519150601f19603f3d011682016040523d82523d6000602084013e612901565b606091505b50509050806117a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906139bc565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205461296c90826126af565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526002602052604090209190915550565b6000826129a857506000610fdd565b828202828482816129b557fe5b04146126ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906140ac565b6000808211612a28576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613e36565b818381612a3157fe5b049392505050565b612a41610fe3565b821415612a5757612a52838261321b565b6117a5565b6000828152600a6020526040902054612a7090826126af565b6000838152600a6020908152604080832093909355600c9052205473ffffffffffffffffffffffffffffffffffffffff1680612ad8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613f84565b60608483604051602401612aed9291906137f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ffd31c5ba00000000000000000000000000000000000000000000000000000000179052517f419cb55000000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff83169063419cb55090612bb690849060040161394c565b600060405180830381600087803b158015612bd057600080fd5b505af1158015612be4573d6000803e3d6000fd5b505050505050505050565b600080825111612c2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906145ac565b815160011415612c515781600081518110612c4257fe5b60200260200101519050610ae6565b612c59613344565b5060408051610200810182527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381527f633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d60208201527f890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d818301527f3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd86060808301919091527fecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da60808301527fdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da560a08301527f617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d760c08301527f292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead60e08301527fe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e106101008301527f7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f826101208301527fe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e836365166101408301527f3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c6101608301527fad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e6101808301527fa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab6101a08301527f4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c8626101c08301527f2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf106101e0830152825183815280820184529192909190602082018180368337505085519192506000918291508180805b60018411156130025750506002820460018084161460005b82811015612f7e578a8160020281518110612f2557fe5b602002602001015196508a8160020260010181518110612f4157fe5b6020026020010151955086602089015285604089015287805190602001208b8281518110612f6b57fe5b6020908102919091010152600101612f0e565b508015612fe157896001850381518110612f9457fe5b60200260200101519550878360108110612faa57fe5b602002015160001b945085602088015284604088015286805190602001208a8381518110612fd457fe5b6020026020010181815250505b80612fed576000612ff0565b60015b60ff1682019350600190920191612ef6565b8960008151811061300f57fe5b602002602001015198505050505050505050919050565b60008184841115613064576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1919061394c565b505050900390565b60008061307842610ead565b9050600080613840600e548161308a57fe5b04905060005b818110156130e057808403600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff8a1684529091529020546130d69084906126af565b9250600101613090565b5090949350505050565b6000808211613125576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613fbb565b816001141561313657506000610ae6565b81600060805b60018110613184577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001821b01811b83161561317c5791821c91908101905b60011c61313c565b506001811b84146126ee576001019392505050565b60008181526005602052604090205460ff16156131e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613e6d565b600090815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600061322783836117aa565b60008181526004602052604090205490915015613270576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614018565b600082116132aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141f8565b6040805160608101825283815260006020808301828152428486019081528684526004909252918490209251835590516001830155516002909101555183907fb33d2162aead99dab59e77a7a67ea025b776bf8ca8079e132afdf9b23e03bd4290613316908590613943565b60405180910390a2505050565b60405180606001604052806000815260200160008152602001600081525090565b6040518061020001604052806010906020820280368337509192915050565b60008083601f840112613374578182fd5b50813567ffffffffffffffff81111561338b578182fd5b60208301915083602080830285010111156133a557600080fd5b9250929050565b6000602082840312156133bd578081fd5b81356126ee81614771565b600080600080606085870312156133dd578283fd5b84356133e881614771565b9350602085013567ffffffffffffffff811115613403578384fd5b61340f87828801613363565b9598909750949560400135949350505050565b60008060408385031215613434578182fd5b823561343f81614771565b946020939093013593505050565b60008060008060008060008060e0898b031215613468578384fd5b883561347381614771565b97506020890135965060408901359550606089013594506080890135935060a089013567ffffffffffffffff8111156134aa578384fd5b6134b68b828c01613363565b999c989b50969995989497949560c00135949350505050565b600080600080608085870312156134e4578384fd5b84356134ef81614771565b966020860135965060408601359560600135945092505050565b6000806000806000806000806000806000806101608d8f03121561352b578384fd5b6135358d35614771565b8c359b5060208d01359a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d0135955060e08d013594506101008d0135935067ffffffffffffffff6101208e0135111561358b578283fd5b61359c8e6101208f01358f01613363565b81945080935050506101408d013590509295989b509295989b509295989b565b6000602082840312156135cd578081fd5b5035919050565b600080604083850312156135e6578182fd5b50508035926020909101359150565b600080600060608486031215613609578283fd5b8335925060208401359150604084013561362281614771565b809150509250925092565b600080600060608486031215613641578081fd5b505081359360208301359350604090920135919050565b6000806040838503121561366a578182fd5b82359150602083013561367c81614771565b809150509250929050565b600080600080600080600060e0888a0312156136a1578081fd5b8735965060208801356136b381614771565b96999698505050506040850135946060810135946080820135945060a0820135935060c0909101359150565b600080600080600080600060e0888a0312156136f9578081fd5b87359650602088013561370b81614771565b955060408801359450606088013593506080880135925060a088013561373081614771565b8092505060c0880135905092959891949750929550565b60008060408385031215613759578182fd5b823591506020830135801515811461367c578182fd5b600080600080600060a08688031215613786578283fd5b505083359560208501359550604085013594606081013594506080013592509050565b600081518084526137c1816020860160208601614745565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b918252602082015260400190565b60008251613813818460208701614745565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff851682526040602083015282604083015282846060840137818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b73ffffffffffffffffffffffffffffffffffffffff9687168152602081019590955260408501939093526060840191909152909216608082015290151560a082015260c00190565b73ffffffffffffffffffffffffffffffffffffffff9687168152602081019590955260408501939093526060840191909152909216608082015260a081019190915260c00190565b901515815260200190565b90815260200190565b6000602082526126ee60208301846137a9565b60208082526027908201527f4c315f4252473a204d757374207472616e736665722061206e6f6e2d7a65726f60408201527f20616d6f756e7400000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f4c315f4554485f4252473a20455448207472616e73666572206661696c656400604082015260600190565b6020808252603b908201527f4c315f4252473a206368616c6c656e6765506572696f64206d7573742062652060408201527f646976697369626c652062792054494d455f534c4f545f53495a450000000000606082015260800190565b6020808252601f908201527f4c315f4252473a2043616c6c6572206973206e6f7420746865206f776e657200604082015260600190565b60208082526028908201527f4c315f4252473a205472616e73666572526f6f7420686173206e6f742062656560408201527f6e20626f6e646564000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f4c325f4252473a207472616e73666572496420686173206e6f20626f6e640000604082015260600190565b6020808252601c908201527f4252473a205472616e7366657220726f6f74206e6f7420666f756e6400000000604082015260600190565b6020808252601e908201527f4143543a204164647265737320697320616c726561647920626f6e6465720000604082015260600190565b6020808252601b908201527f4252473a205472616e73666572526f6f74206e6f7420666f756e640000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526025908201527f4c315f4252473a205472616e73666572526f6f7420616c72656164792072657360408201527f6f6c766564000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4c315f4252473a205472616e73666572526f6f7420616c72656164792063686160408201527f6c6c656e67656400000000000000000000000000000000000000000000000000606082015260800190565b6020808252603b908201527f4252473a205472616e73666572526f6f742063616e6e6f74206265207265736360408201527f756564206265666f726520746865205265736375652044656c61790000000000606082015260800190565b6020808252601a908201527f4143543a2041646472657373206973206e6f7420626f6e646572000000000000604082015260600190565b60208082526028908201527f4c315f4252473a2053656e647320746f207468697320636861696e496420617260408201527f6520706175736564000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252602e908201527f4c315f4252473a20726f6f74436f6d6d69747465644174206d7573742062652060408201527f67726561746572207468616e2030000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602c908201527f4252473a20546865207472616e736665722068617320616c726561647920626560408201527f656e2077697468647261776e0000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4c315f4554485f4252473a2056616c756520646f6573206e6f74206d6174636860408201527f20616d6f756e7400000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4c69625f4d65726b6c65547265653a20496e646578206f7574206f6620626f7560408201527f6e64732e00000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f4c315f4252473a20636861696e4964206e6f7420737570706f72746564000000604082015260600190565b60208082526030908201527f4c69625f4d65726b6c65547265653a2043616e6e6f7420636f6d70757465206360408201527f65696c286c6f675f3229206f6620302e00000000000000000000000000000000606082015260800190565b6020808252601e908201527f4252473a205472616e7366657220726f6f7420616c7265616479207365740000604082015260600190565b60208082526026908201527f4c315f4252473a205472616e73666572526f6f7420616c726561647920636f6e60408201527f6669726d65640000000000000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602f908201527f4c315f4252473a205472616e73666572526f6f742068617320616c726561647960408201527f206265656e20636f6e6669726d65640000000000000000000000000000000000606082015260800190565b60208082526037908201527f4c69625f4d65726b6c65547265653a20546f74616c206c6561766573206d757360408201527f742062652067726561746572207468616e207a65726f2e000000000000000000606082015260800190565b6020808252818101527f4143543a204e6f7420656e6f75676820617661696c61626c6520637265646974604082015260600190565b6020808252602d908201527f4252473a2043616e6e6f7420736574205472616e73666572526f6f7420746f7460408201527f616c416d6f756e74206f66203000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f4143543a2043616c6c6572206973206e6f7420626f6e64657200000000000000604082015260600190565b6020808252601b908201527f4252473a20496e76616c6964207472616e736665722070726f6f660000000000604082015260600190565b602080825260409082018190527f4c315f4252473a205472616e73666572526f6f742063616e6e6f742062652063908201527f68616c6c656e676564206166746572206368616c6c656e676520706572696f64606082015260800190565b60208082526026908201527f4c315f4252473a204368616c6c656e676520706572696f6420686173206e6f7460408201527f20656e6465640000000000000000000000000000000000000000000000000000606082015260800190565b6020808252604d908201527f4c69625f4d65726b6c65547265653a20546f74616c207369626c696e6773206460408201527f6f6573206e6f7420636f72726563746c7920636f72726573706f6e6420746f2060608201527f746f74616c206c65617665732e00000000000000000000000000000000000000608082015260a00190565b60208082526027908201527f4252473a205769746864726177616c2068617320616c7265616479206265656e60408201527f20626f6e64656400000000000000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f4c315f4252473a205472616e73666572526f6f7420686173206e6f742062656560408201527f6e206368616c6c656e6765640000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4252473a205769746864726177616c2065786365656473205472616e7366657260408201527f526f6f7420746f74616c00000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602b908201527f4c315f4252473a205f6e6577476f7665726e616e63652063616e6e6f7420626560408201527f2061646472657373283029000000000000000000000000000000000000000000606082015260800190565b60208082526034908201527f4c69625f4d65726b6c65547265653a204d7573742070726f766964652061742060408201527f6c65617374206f6e65206c65616620686173682e000000000000000000000000606082015260800190565b6020808252602c908201527f4c315f4252473a205472616e73666572526f6f742068617320616c726561647960408201527f206265656e20626f6e6465640000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4c315f4252473a2052656c61796572206665652063616e6e6f7420657863656560408201527f6420616d6f756e74000000000000000000000000000000000000000000000000606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b96875273ffffffffffffffffffffffffffffffffffffffff95909516602087015260408601939093526060850191909152608084015260a083015260c082015260e00190565b93845260208401929092526040830152606082015260800190565b60005b83811015614760578181015183820152602001614748565b83811115610ea75750506000910152565b73ffffffffffffffffffffffffffffffffffffffff81168114610fa857600080fdfe4c315f4252473a20416d6f756e74206578636565647320636861696e42616c616e63652e205468697320696e646963617465732061206c617965722d32206661696c7572652ea2646970667358221220059efbacfa8e4391e713a70ec9b5c2c2563c7f47558e9ce3c7e1c29a5888cbe664736f6c634300060c00330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000f56e305024b195383245a075737d16dbdb8487fb00000000000000000000000000000000000000000000000000000000000000020000000000000000000000002a6303e6b99d451df3566068ebb110708335658f0000000000000000000000009137a628546e2b1bc26f60a5d1262fb6d58ea44aDeployed Bytecode
0x6080604052600436106102f25760003560e01c806381707b801161018f578063cbd1642e116100e1578063eecd57e61161008a578063fa2a69a311610064578063fa2a69a314610814578063fc110b6714610834578063ffa9286c14610854576102f2565b8063eecd57e6146107bf578063ef6ebe5e146107df578063f3f480d9146107ff576102f2565b8063d5ef7551116100bb578063d5ef75511461076c578063deace8f51461078c578063e19be1501461079f576102f2565b8063cbd1642e146106ff578063ce803b4f1461071f578063d44481631461074c576102f2565b8063a35962f311610143578063af215f941161011d578063af215f941461069f578063b162717e146106bf578063c7525dd3146106df576102f2565b8063a35962f31461064c578063ab033ea91461066c578063adc9772e1461068c576102f2565b8063960a7afa11610174578063960a7afa146105f757806398c4f76d14610617578063a239f5ee1461062c576102f2565b806381707b80146105b75780638d8798bf146105d7576102f2565b80633a7af631116102485780635a7e1083116101fc5780636cff06a7116101d65780636cff06a71461056d5780637398d28214610582578063767631d5146105a2576102f2565b80635a7e1083146104f95780635aa6e6751461052b5780635d475fdd1461054d576102f2565b80634de8c6e61161022d5780634de8c6e6146104a45780635325937f146104b957806357344e6f146104d9576102f2565b80633a7af631146104575780633b8fea2814610484576102f2565b806323c452cd116102aa578063302830ab11610284578063302830ab146104025780633408e4701461042257806339ada66914610437576102f2565b806323c452cd146103a25780632b85dcc9146103c25780632e17de78146103e2576102f2565b806313948c76116102db57806313948c7614610339578063149420241461036f5780631bbe15ea1461038f576102f2565b806304e6c2c0146102f75780630f7aadb714610319575b600080fd5b34801561030357600080fd5b506103176103123660046133ac565b610874565b005b34801561032557600080fd5b50610317610334366004613509565b61095e565b34801561034557600080fd5b506103596103543660046133ac565b610abf565b6040516103669190613943565b60405180910390f35b34801561037b57600080fd5b5061031761038a366004613747565b610aeb565b61031761039d36600461362d565b610b31565b3480156103ae57600080fd5b506103176103bd3660046134cf565b610d9b565b3480156103ce57600080fd5b506103596103dd3660046135bc565b610ead565b3480156103ee57600080fd5b506103176103fd3660046135bc565b610eb5565b34801561040e57600080fd5b5061035961041d366004613422565b610fab565b34801561042e57600080fd5b50610359610fe3565b34801561044357600080fd5b506103176104523660046135bc565b610fe7565b34801561046357600080fd5b506104776104723660046135bc565b610ff4565b6040516103669190613938565b34801561049057600080fd5b5061035961049f3660046135d4565b611009565b3480156104b057600080fd5b50610359611026565b3480156104c557600080fd5b506103176104d43660046133ac565b61102c565b3480156104e557600080fd5b506103596104f43660046133ac565b61110e565b34801561050557600080fd5b506105196105143660046135bc565b611136565b604051610366969594939291906138a8565b34801561053757600080fd5b5061054061119a565b604051610366919061381d565b34801561055957600080fd5b506103176105683660046135bc565b6111b6565b34801561057957600080fd5b506103596111ff565b34801561058e57600080fd5b5061035961059d366004613658565b611205565b3480156105ae57600080fd5b50610359611222565b3480156105c357600080fd5b506103176105d236600461362d565b611228565b3480156105e357600080fd5b506103176105f236600461362d565b6114dc565b34801561060357600080fd5b506103596106123660046135d4565b6117aa565b34801561062357600080fd5b506103596117dd565b34801561063857600080fd5b506103596106473660046135bc565b6117e2565b34801561065857600080fd5b506105406106673660046135bc565b6117ef565b34801561067857600080fd5b506103176106873660046133ac565b611817565b61031761069a366004613422565b6118b3565b3480156106ab57600080fd5b506103596106ba366004613687565b6119c4565b3480156106cb57600080fd5b506103176106da3660046133c8565b611a06565b3480156106eb57600080fd5b506103176106fa36600461344d565b611b83565b34801561070b57600080fd5b5061031761071a3660046135f5565b611d0a565b34801561072b57600080fd5b5061073f61073a3660046135d4565b611e01565b60405161036691906146c3565b34801561075857600080fd5b50610317610767366004613658565b611e56565b34801561077857600080fd5b506104776107873660046133ac565b611eb1565b61031761079a3660046136df565b611edc565b3480156107ab57600080fd5b506103596107ba3660046135bc565b6121b9565b3480156107cb57600080fd5b506103176107da3660046135bc565b6121ce565b3480156107eb57600080fd5b506103176107fa36600461376f565b6121db565b34801561080b57600080fd5b506103596123c4565b34801561082057600080fd5b5061047761082f3660046135bc565b6123ca565b34801561084057600080fd5b5061035961084f3660046135bc565b6123df565b34801561086057600080fd5b5061035961086f3660046133ac565b6123f1565b61087c61242b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602081905260409091205460ff161515146108ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613d0e565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660008181526001602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f4234ba611d325b3ba434c4e1b037967b955b1274d4185ee9847b7491111a48ff9190a250565b6002600054141561099b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b600260009081556109b86109ad610fe3565b8e8e8e8e8e8e6119c4565b90506109fe81868686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d95949392508891505061247e565b610a34576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061428c565b6000610a4088886117aa565b9050610a4c818e6125e8565b610a59828f8f6000612688565b8d73ffffffffffffffffffffffffffffffffffffffff16827f9475cdbde5fc71fe2ccd413c82878ee54d061b9f74f9e2e1a03ff1178821502c8f8f604051610aa29291906137f3565b60405180910390a350506001600055505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260409020545b919050565b610af361242b565b6000918252600d602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6000610b3d84846117aa565b600081815260086020908152604080832086845260078352818420858552909252909120549192509015610b9d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614109565b6001810154610bd8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613a87565b6000610bf3600e5483600101546126af90919063ffffffff16565b905042811015610c2f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906142c3565b600382015415610c6b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613c54565b4260038301556004820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790556001820154600090610cae90610ead565b90506000610cbb876121b9565b8454600084815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff9094168084529390915290205491925090610cfe90836126f5565b600084815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff80871685529252909120919091558554610d3f911683612737565b6000610d4a896117e2565b9050610d563382612794565b89877fec2697dcba539a0ac947cdf1f6d0b6314c065429eca8be2435859b10209d4c278b604051610d879190613943565b60405180910390a350505050505050505050565b3360009081526001602052604090205460ff16610de4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614255565b60026000541415610e21576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b60026000908155610e3f610e33610fe3565b868686866000806119c4565b9050610e4b81856127d1565b610e5781868685612688565b506001600055610e66336123f1565b610e6f3361110e565b1015610ea7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141c3565b50505050565b613840900490565b60026000541415610ef2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b6002600055610f013382612737565b610f0b3382612888565b3373ffffffffffffffffffffffffffffffffffffffff167f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd82604051610f519190613943565b60405180910390a26001600055610f67336123f1565b610f703361110e565b1015610fa8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141c3565b50565b73ffffffffffffffffffffffffffffffffffffffff821660009081526006602090815260408083208484529091529020545b92915050565b4690565b610fef61242b565b601055565b60009081526005602052604090205460ff1690565b600760209081526000928352604080842090915290825290205481565b61384081565b61103461242b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604090205460ff1615611094576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613b52565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155517f2cec73b7434d3b91198ad1a618f63e6a0761ce281af5ec9ec76606d948d03e239190a250565b73ffffffffffffffffffffffffffffffffffffffff1660009081526002602052604090205490565b6008602052600090815260409020805460018201546002830154600384015460049094015473ffffffffffffffffffffffffffffffffffffffff93841694929391929181169074010000000000000000000000000000000000000000900460ff1686565b600b5473ffffffffffffffffffffffffffffffffffffffff1681565b6111be61242b565b6138408106156111fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906139f3565b600e55565b60105481565b600960209081526000928352604080842090915290825290205481565b600f5481565b600061123484846117aa565b6000818152600860205260409020600381015491925090611281576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061445e565b600f546003820154611292916126af565b42116112ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614321565b600481015474010000000000000000000000000000000000000000900460ff1615611321576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613bf7565b6004810180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055600061136d856117e2565b6000858152600760209081526040808320878452909152902054909150156114485760105460008581526007602090815260408083208784529091529020546113b5916126af565b826001015411156113f95781546113f49073ffffffffffffffffffffffffffffffffffffffff166113ef836113e9896121b9565b906126af565b61293c565b611443565b600482015461141e9073ffffffffffffffffffffffffffffffffffffffff168261293c565b81546114439073ffffffffffffffffffffffffffffffffffffffff166113ef876121b9565b61149b565b61146961dead611464600461145e856001612999565b906129ed565b612888565b60048083015461149b9173ffffffffffffffffffffffffffffffffffffffff909116906113ef9061145e856007612999565b85837f4a99228a8a6d774d261be57ab0ed833bb1bae1f22bbbd3d4767b75ad03fdddf7876040516114cc9190613943565b60405180910390a3505050505050565b3360009081526001602052604090205460ff16611525576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614255565b600061153184836117aa565b600084815260076020908152604080832084845290915290205490915015611585576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614109565b600081815260086020526040902060010154156115ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614609565b60006115d942610ead565b905060006115e6846121b9565b600083815260096020908152604080832033845290915290205490915061160d90826126af565b60008381526009602090815260408083203380855290835281842094909455805160c08101825293845242848301908152848201898152606086018581526080870186815260a088018781528b88526008909652939095209551865473ffffffffffffffffffffffffffffffffffffffff9182167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161788559251600188015590516002870155935160038601559051600490940180549251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff95909416929091169190911792909216179055611720868686612a39565b857fa57b3e1f3af9eca02201028629700658608222c365064584cfe65d9630ef4f7b856040516117509190613943565b60405180910390a2505050611764336123f1565b61176d3361110e565b10156117a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141c3565b505050565b600082826040516020016117bf9291906137f3565b60405160208183030381529060405280519060200120905092915050565b600a81565b6000610fdd82600a6129ed565b600c6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b61181f61242b565b73ffffffffffffffffffffffffffffffffffffffff811661186c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061454f565b600b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600260005414156118f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614518565b6002600090815573ffffffffffffffffffffffffffffffffffffffff831681526001602081905260409091205460ff16151514611959576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613d0e565b6119633382612794565b61196d828261293c565b8173ffffffffffffffffffffffffffffffffffffffff167febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a826040516119b39190613943565b60405180910390a250506001600055565b6000878787878787876040516020016119e397969594939291906146e4565b604051602081830303815290604052805190602001209050979650505050505050565b6000611a44848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612bef92505050565b90506000611a5282846117aa565b90506000805b85811015611b165773ffffffffffffffffffffffffffffffffffffffff8816600090815260066020526040812081898985818110611a9257fe5b9050602002013581526020019081526020016000205490506000811115611b0d57611abd83826126af565b73ffffffffffffffffffffffffffffffffffffffff8a16600090815260066020526040812091945090818a8a86818110611af357fe5b905060200201358152602001908152602001600020819055505b50600101611a58565b50611b2182826125e8565b611b2b878261293c565b828773ffffffffffffffffffffffffffffffffffffffff167f78e830d08be9d5f957414c84d685c061ecbd8467be98b42ebb64f0118b57d2ff83604051611b729190613943565b60405180910390a350505050505050565b611bc787858585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c95949392508791505061247e565b611bfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061428c565b6000611c0987876117aa565b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526006602090815260408083208c845290915290205490915080611c74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613ae4565b73ffffffffffffffffffffffffffffffffffffffff8a1660009081526006602090815260408083208c8452909152812055611caf82826125e8565b611cb98a8261293c565b87898b73ffffffffffffffffffffffffffffffffffffffff167f84eb21b24c31b27a3bc67dde4a598aad06db6e9415cd66544492b9616996143c60405160405180910390a450505050505050505050565b611d1261242b565b6000611d1e84846117aa565b9050611d28613323565b611d328585611e01565b9050806040015160001415611d73576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613b89565b80518414611d7d57fe5b6040810151600090611d92906249d4006126af565b905080421015611dce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613cb1565b60208201518251600091611de291906126f5565b9050611dee84826125e8565b611df88582612888565b50505050505050565b611e09613323565b60046000611e1785856117aa565b81526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905092915050565b611e5e61242b565b6000918252600c602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604090205460ff1690565b6000878152600c602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611f38576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613f84565b6000888152600d602052604090205460ff1615611f81576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613d45565b60008611611fbb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061395f565b81861015611ff5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614666565b611fff3387612794565b606087878787878760405160240161201c969594939291906138f0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcc29a3060000000000000000000000000000000000000000000000000000000017905260008c8152600a90915220549091506120ac90886126af565b60008a8152600a60205260409081902091909155517f419cb55000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063419cb5509061211090849060040161394c565b600060405180830381600087803b15801561212a57600080fd5b505af115801561213e573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a7f0a0607688c86ec1775abcdbab7b33a3a35a6c9cde677c9be880150c231cc6b0b8a8a8a896040516121a6949392919061472a565b60405180910390a4505050505050505050565b6000610fdd6121c7836117e2565b83906126af565b6121d661242b565b600f55565b6000858152600c60205260408082205490517f99178dd8000000000000000000000000000000000000000000000000000000008152879273ffffffffffffffffffffffffffffffffffffffff9092169182916399178dd89161224491339190369060040161383e565b600060405180830381600087803b15801561225e57600080fd5b505af1158015612272573d6000803e3d6000fd5b50505050600061228287866117aa565b6000878152600760209081526040808320848452909152902054909150156122d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061404f565b60008411612310576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613dd9565b600086815260076020908152604080832084845282529182902086905581516080810190925260468083526123619288929091906147949083013960008b8152600a60205260409020549190613026565b6000898152600a60209081526040808320939093558382526008905220600181015461239257612392888888612a39565b87878a7ffdfb0eefa96935b8a8c0edf528e125dc6f3934fdbbfce31b38967e8ff413dccd896040516121a69190613943565b600e5481565b600d6020526000908152604090205460ff1681565b600a6020526000908152604090205481565b6000610fdd6123ff8361306c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260036020526040902054906126af565b600b5473ffffffffffffffffffffffffffffffffffffffff16331461247c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613a50565b565b60008082116124b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614166565b8184106124f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613f27565b6124fb826130ea565b835114612534576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e19061437e565b8460005b84518110156125db5785600116600114156125905784818151811061255957fe5b6020026020010151826040516020016125739291906137f3565b6040516020818303038152906040528051906020012091506125cf565b8185828151811061259d57fe5b60200260200101516040516020016125b69291906137f3565b6040516020818303038152906040528051906020012091505b600195861c9501612538565b5090951495945050505050565b6000828152600460205260409020805461262e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613b1b565b600181015460009061264090846126af565b825490915081111561267e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906144bb565b6001909101555050565b61269184613199565b61269f8361146484846126f5565b8015610ea757610ea73382612888565b6000828201838110156126ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613bc0565b9392505050565b600082821115612731576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613da2565b50900390565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205461276790826126af565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526003602052604090209190915550565b8034146127cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613eca565b5050565b33600090815260066020908152604080832085845290915290205415612823576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614401565b61282d3382612737565b336000908152600660209081526040808320858452909152908190208290555182907f0c3d250c7831051e78aa6a56679e590374c7c424415ffe4aa474491def2fe7059061287c908490613943565b60405180910390a25050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516128bf9190613801565b60006040518083038185875af1925050503d80600081146128fc576040519150601f19603f3d011682016040523d82523d6000602084013e612901565b606091505b50509050806117a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906139bc565b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205461296c90826126af565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526002602052604090209190915550565b6000826129a857506000610fdd565b828202828482816129b557fe5b04146126ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906140ac565b6000808211612a28576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613e36565b818381612a3157fe5b049392505050565b612a41610fe3565b821415612a5757612a52838261321b565b6117a5565b6000828152600a6020526040902054612a7090826126af565b6000838152600a6020908152604080832093909355600c9052205473ffffffffffffffffffffffffffffffffffffffff1680612ad8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613f84565b60608483604051602401612aed9291906137f3565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ffd31c5ba00000000000000000000000000000000000000000000000000000000179052517f419cb55000000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff83169063419cb55090612bb690849060040161394c565b600060405180830381600087803b158015612bd057600080fd5b505af1158015612be4573d6000803e3d6000fd5b505050505050505050565b600080825111612c2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906145ac565b815160011415612c515781600081518110612c4257fe5b60200260200101519050610ae6565b612c59613344565b5060408051610200810182527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381527f633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d60208201527f890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d818301527f3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd86060808301919091527fecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da60808301527fdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da560a08301527f617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d760c08301527f292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead60e08301527fe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e106101008301527f7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f826101208301527fe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e836365166101408301527f3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c6101608301527fad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e6101808301527fa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab6101a08301527f4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c8626101c08301527f2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf106101e0830152825183815280820184529192909190602082018180368337505085519192506000918291508180805b60018411156130025750506002820460018084161460005b82811015612f7e578a8160020281518110612f2557fe5b602002602001015196508a8160020260010181518110612f4157fe5b6020026020010151955086602089015285604089015287805190602001208b8281518110612f6b57fe5b6020908102919091010152600101612f0e565b508015612fe157896001850381518110612f9457fe5b60200260200101519550878360108110612faa57fe5b602002015160001b945085602088015284604088015286805190602001208a8381518110612fd457fe5b6020026020010181815250505b80612fed576000612ff0565b60015b60ff1682019350600190920191612ef6565b8960008151811061300f57fe5b602002602001015198505050505050505050919050565b60008184841115613064576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1919061394c565b505050900390565b60008061307842610ead565b9050600080613840600e548161308a57fe5b04905060005b818110156130e057808403600090815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff8a1684529091529020546130d69084906126af565b9250600101613090565b5090949350505050565b6000808211613125576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613fbb565b816001141561313657506000610ae6565b81600060805b60018110613184577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001821b01811b83161561317c5791821c91908101905b60011c61313c565b506001811b84146126ee576001019392505050565b60008181526005602052604090205460ff16156131e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190613e6d565b600090815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600061322783836117aa565b60008181526004602052604090205490915015613270576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e190614018565b600082116132aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e1906141f8565b6040805160608101825283815260006020808301828152428486019081528684526004909252918490209251835590516001830155516002909101555183907fb33d2162aead99dab59e77a7a67ea025b776bf8ca8079e132afdf9b23e03bd4290613316908590613943565b60405180910390a2505050565b60405180606001604052806000815260200160008152602001600081525090565b6040518061020001604052806010906020820280368337509192915050565b60008083601f840112613374578182fd5b50813567ffffffffffffffff81111561338b578182fd5b60208301915083602080830285010111156133a557600080fd5b9250929050565b6000602082840312156133bd578081fd5b81356126ee81614771565b600080600080606085870312156133dd578283fd5b84356133e881614771565b9350602085013567ffffffffffffffff811115613403578384fd5b61340f87828801613363565b9598909750949560400135949350505050565b60008060408385031215613434578182fd5b823561343f81614771565b946020939093013593505050565b60008060008060008060008060e0898b031215613468578384fd5b883561347381614771565b97506020890135965060408901359550606089013594506080890135935060a089013567ffffffffffffffff8111156134aa578384fd5b6134b68b828c01613363565b999c989b50969995989497949560c00135949350505050565b600080600080608085870312156134e4578384fd5b84356134ef81614771565b966020860135965060408601359560600135945092505050565b6000806000806000806000806000806000806101608d8f03121561352b578384fd5b6135358d35614771565b8c359b5060208d01359a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d0135955060e08d013594506101008d0135935067ffffffffffffffff6101208e0135111561358b578283fd5b61359c8e6101208f01358f01613363565b81945080935050506101408d013590509295989b509295989b509295989b565b6000602082840312156135cd578081fd5b5035919050565b600080604083850312156135e6578182fd5b50508035926020909101359150565b600080600060608486031215613609578283fd5b8335925060208401359150604084013561362281614771565b809150509250925092565b600080600060608486031215613641578081fd5b505081359360208301359350604090920135919050565b6000806040838503121561366a578182fd5b82359150602083013561367c81614771565b809150509250929050565b600080600080600080600060e0888a0312156136a1578081fd5b8735965060208801356136b381614771565b96999698505050506040850135946060810135946080820135945060a0820135935060c0909101359150565b600080600080600080600060e0888a0312156136f9578081fd5b87359650602088013561370b81614771565b955060408801359450606088013593506080880135925060a088013561373081614771565b8092505060c0880135905092959891949750929550565b60008060408385031215613759578182fd5b823591506020830135801515811461367c578182fd5b600080600080600060a08688031215613786578283fd5b505083359560208501359550604085013594606081013594506080013592509050565b600081518084526137c1816020860160208601614745565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b918252602082015260400190565b60008251613813818460208701614745565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff851682526040602083015282604083015282846060840137818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b73ffffffffffffffffffffffffffffffffffffffff9687168152602081019590955260408501939093526060840191909152909216608082015290151560a082015260c00190565b73ffffffffffffffffffffffffffffffffffffffff9687168152602081019590955260408501939093526060840191909152909216608082015260a081019190915260c00190565b901515815260200190565b90815260200190565b6000602082526126ee60208301846137a9565b60208082526027908201527f4c315f4252473a204d757374207472616e736665722061206e6f6e2d7a65726f60408201527f20616d6f756e7400000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f4c315f4554485f4252473a20455448207472616e73666572206661696c656400604082015260600190565b6020808252603b908201527f4c315f4252473a206368616c6c656e6765506572696f64206d7573742062652060408201527f646976697369626c652062792054494d455f534c4f545f53495a450000000000606082015260800190565b6020808252601f908201527f4c315f4252473a2043616c6c6572206973206e6f7420746865206f776e657200604082015260600190565b60208082526028908201527f4c315f4252473a205472616e73666572526f6f7420686173206e6f742062656560408201527f6e20626f6e646564000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f4c325f4252473a207472616e73666572496420686173206e6f20626f6e640000604082015260600190565b6020808252601c908201527f4252473a205472616e7366657220726f6f74206e6f7420666f756e6400000000604082015260600190565b6020808252601e908201527f4143543a204164647265737320697320616c726561647920626f6e6465720000604082015260600190565b6020808252601b908201527f4252473a205472616e73666572526f6f74206e6f7420666f756e640000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526025908201527f4c315f4252473a205472616e73666572526f6f7420616c72656164792072657360408201527f6f6c766564000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4c315f4252473a205472616e73666572526f6f7420616c72656164792063686160408201527f6c6c656e67656400000000000000000000000000000000000000000000000000606082015260800190565b6020808252603b908201527f4252473a205472616e73666572526f6f742063616e6e6f74206265207265736360408201527f756564206265666f726520746865205265736375652044656c61790000000000606082015260800190565b6020808252601a908201527f4143543a2041646472657373206973206e6f7420626f6e646572000000000000604082015260600190565b60208082526028908201527f4c315f4252473a2053656e647320746f207468697320636861696e496420617260408201527f6520706175736564000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252602e908201527f4c315f4252473a20726f6f74436f6d6d69747465644174206d7573742062652060408201527f67726561746572207468616e2030000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602c908201527f4252473a20546865207472616e736665722068617320616c726561647920626560408201527f656e2077697468647261776e0000000000000000000000000000000000000000606082015260800190565b60208082526027908201527f4c315f4554485f4252473a2056616c756520646f6573206e6f74206d6174636860408201527f20616d6f756e7400000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4c69625f4d65726b6c65547265653a20496e646578206f7574206f6620626f7560408201527f6e64732e00000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601d908201527f4c315f4252473a20636861696e4964206e6f7420737570706f72746564000000604082015260600190565b60208082526030908201527f4c69625f4d65726b6c65547265653a2043616e6e6f7420636f6d70757465206360408201527f65696c286c6f675f3229206f6620302e00000000000000000000000000000000606082015260800190565b6020808252601e908201527f4252473a205472616e7366657220726f6f7420616c7265616479207365740000604082015260600190565b60208082526026908201527f4c315f4252473a205472616e73666572526f6f7420616c726561647920636f6e60408201527f6669726d65640000000000000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602f908201527f4c315f4252473a205472616e73666572526f6f742068617320616c726561647960408201527f206265656e20636f6e6669726d65640000000000000000000000000000000000606082015260800190565b60208082526037908201527f4c69625f4d65726b6c65547265653a20546f74616c206c6561766573206d757360408201527f742062652067726561746572207468616e207a65726f2e000000000000000000606082015260800190565b6020808252818101527f4143543a204e6f7420656e6f75676820617661696c61626c6520637265646974604082015260600190565b6020808252602d908201527f4252473a2043616e6e6f7420736574205472616e73666572526f6f7420746f7460408201527f616c416d6f756e74206f66203000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f4143543a2043616c6c6572206973206e6f7420626f6e64657200000000000000604082015260600190565b6020808252601b908201527f4252473a20496e76616c6964207472616e736665722070726f6f660000000000604082015260600190565b602080825260409082018190527f4c315f4252473a205472616e73666572526f6f742063616e6e6f742062652063908201527f68616c6c656e676564206166746572206368616c6c656e676520706572696f64606082015260800190565b60208082526026908201527f4c315f4252473a204368616c6c656e676520706572696f6420686173206e6f7460408201527f20656e6465640000000000000000000000000000000000000000000000000000606082015260800190565b6020808252604d908201527f4c69625f4d65726b6c65547265653a20546f74616c207369626c696e6773206460408201527f6f6573206e6f7420636f72726563746c7920636f72726573706f6e6420746f2060608201527f746f74616c206c65617665732e00000000000000000000000000000000000000608082015260a00190565b60208082526027908201527f4252473a205769746864726177616c2068617320616c7265616479206265656e60408201527f20626f6e64656400000000000000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f4c315f4252473a205472616e73666572526f6f7420686173206e6f742062656560408201527f6e206368616c6c656e6765640000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4252473a205769746864726177616c2065786365656473205472616e7366657260408201527f526f6f7420746f74616c00000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252602b908201527f4c315f4252473a205f6e6577476f7665726e616e63652063616e6e6f7420626560408201527f2061646472657373283029000000000000000000000000000000000000000000606082015260800190565b60208082526034908201527f4c69625f4d65726b6c65547265653a204d7573742070726f766964652061742060408201527f6c65617374206f6e65206c65616620686173682e000000000000000000000000606082015260800190565b6020808252602c908201527f4c315f4252473a205472616e73666572526f6f742068617320616c726561647960408201527f206265656e20626f6e6465640000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4c315f4252473a2052656c61796572206665652063616e6e6f7420657863656560408201527f6420616d6f756e74000000000000000000000000000000000000000000000000606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b96875273ffffffffffffffffffffffffffffffffffffffff95909516602087015260408601939093526060850191909152608084015260a083015260c082015260e00190565b93845260208401929092526040830152606082015260800190565b60005b83811015614760578181015183820152602001614748565b83811115610ea75750506000910152565b73ffffffffffffffffffffffffffffffffffffffff81168114610fa857600080fdfe4c315f4252473a20416d6f756e74206578636565647320636861696e42616c616e63652e205468697320696e646963617465732061206c617965722d32206661696c7572652ea2646970667358221220059efbacfa8e4391e713a70ec9b5c2c2563c7f47558e9ce3c7e1c29a5888cbe664736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000f56e305024b195383245a075737d16dbdb8487fb00000000000000000000000000000000000000000000000000000000000000020000000000000000000000002a6303e6b99d451df3566068ebb110708335658f0000000000000000000000009137a628546e2b1bc26f60a5d1262fb6d58ea44a
-----Decoded View---------------
Arg [0] : bonders (address[]): 0x2A6303e6b99d451Df3566068EBb110708335658f,0x9137a628546e2b1bc26F60A5D1262fb6D58eA44A
Arg [1] : _governance (address): 0xF56e305024B195383245A075737d16dBdb8487Fb
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 000000000000000000000000f56e305024b195383245a075737d16dbdb8487fb
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [3] : 0000000000000000000000002a6303e6b99d451df3566068ebb110708335658f
Arg [4] : 0000000000000000000000009137a628546e2b1bc26f60a5d1262fb6d58ea44aLoading...LoadingLoading...Loading
Loading...Loading
Loading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingMultichain Portfolio | 30 Chains
Chain Token Portfolio % Price Amount Value ETH Ether (ETH)100.00% $3,375.97 6,644.9345 $22,433,066.4 ETH <0.01% $23.87 30.722 $733.33 ETH <0.01% $0.99853 91.4165 $91.28 ETH <0.01% $0.998753 44.8817 $44.83 ETH <0.01% $0.000029 111,858.1012 $3.28 ETH <0.01% <$0.000001 41,292,938.5214 $0.1634 BSC <0.01% $686.84 0.0665 $45.69 BASE <0.01% $3,373.2 0.00057197 $1.93 FTM <0.01% $1.02 0.6 $0.609142 OP <0.01% $1 0.11 $0.11 GNO <0.01% $0.999795 0.002 $0.002 Loading...Loading[ Download: CSV Export ][ Download: CSV Export ]A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.
Address QR Code
My Address - Private Name Tag or Note
My Name Tag:
Private Name Tags (up to 35 characters) can be used for easy identification of addressesPrivate Note:
A private note (up to 500 characters) can be attached to this address.
Please DO NOT store any passwords or private keys here.Compiler specific version warnings:
The compiled contract might be susceptible to FullInlinerNonExpressionSplitArgumentEvaluationOrder (low-severity), MissingSideEffectsOnSelectorAccess (low-severity), AbiReencodingHeadOverflowWithStaticArrayCleanup (medium-severity), DirtyBytesArrayToStorage (low-severity), DataLocationChangeInInternalOverride (very low-severity), NestedCalldataArrayAbiReencodingSizeValidation (very low-severity), SignedImmutables (very low-severity), ABIDecodeTwoDimensionalArrayMemory (very low-severity), KeccakCaching (medium-severity), EmptyByteArrayCopy (medium-severity), DynamicArrayCleanup (medium-severity) Solidity Compiler Bugs.
Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.SignIn
Address Cards
To use this feature, please login to your Etherscan account and return to this page.Before You Copy
Transaction Private Note
This website uses cookies to improve your experience. By continuing to use this website, you agree to its Terms and Privacy Policy.