false
false

Contract Address Details

0x391c9b3cb3cae0a653295f42267dab8b0505e760

Contract Name
L2ERC20Gateway
Creator
0x88888a–872063 at 0xb90ab1–194e23
Balance
0 ETH ( )
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
89620955
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
L2ERC20Gateway




Optimization enabled
true
Compiler version
v0.6.11+commit.5ef660b1




Optimization runs
100
Verified at
2023-08-24T12:54:51.254000Z

contracts/tokenbridge/arbitrum/gateway/L2ERC20Gateway.sol

// SPDX-License-Identifier: Apache-2.0

/*
 * Copyright 2020, Offchain Labs, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

pragma solidity ^0.6.11;

import "@openzeppelin/contracts/proxy/UpgradeableBeacon.sol";
import "@openzeppelin/contracts/utils/Create2.sol";
import "./L2ArbitrumGateway.sol";
import "../StandardArbERC20.sol";
import "../../libraries/ClonableBeaconProxy.sol";

contract L2ERC20Gateway is L2ArbitrumGateway {
    address public beaconProxyFactory;

    function initialize(
        address _l1Counterpart,
        address _router,
        address _beaconProxyFactory
    ) public {
        L2ArbitrumGateway._initialize(_l1Counterpart, _router);
        require(_beaconProxyFactory != address(0), "INVALID_BEACON");
        beaconProxyFactory = _beaconProxyFactory;
    }

    /**
     * @notice Calculate the address used when bridging an ERC20 token
     * @dev the L1 and L2 address oracles may not always be in sync.
     * For example, a custom token may have been registered but not deploy or the contract self destructed.
     * @param l1ERC20 address of L1 token
     * @return L2 address of a bridged ERC20 token
     */
    function calculateL2TokenAddress(address l1ERC20)
        public
        view
        virtual
        override
        returns (address)
    {
        // this method is marked virtual to be overriden in subclasses used in testing
        return
            BeaconProxyFactory(beaconProxyFactory).calculateExpectedAddress(
                address(this),
                getUserSalt(l1ERC20)
            );
    }

    function cloneableProxyHash() public view returns (bytes32) {
        return BeaconProxyFactory(beaconProxyFactory).cloneableProxyHash();
    }

    function getUserSalt(address l1ERC20) public pure returns (bytes32) {
        return keccak256(abi.encode(l1ERC20));
    }

    /**
     * @notice internal utility function used to deploy ERC20 tokens with the beacon proxy pattern.
     * @dev the transparent proxy implementation by OpenZeppelin can't be used if we want to be able to
     * upgrade the token logic.
     * @param l1ERC20 L1 address of ERC20
     * @param expectedL2Address L2 address of ERC20
     * @param deployData encoded symbol/name/decimal data for initial deploy
     */
    function handleNoContract(
        address l1ERC20,
        address expectedL2Address,
        address _from,
        address, /* _to */
        uint256 _amount,
        bytes memory deployData
    ) internal override returns (bool shouldHalt) {
        bytes32 userSalt = getUserSalt(l1ERC20);
        address createdContract = BeaconProxyFactory(beaconProxyFactory).createProxy(userSalt);

        StandardArbERC20(createdContract).bridgeInit(l1ERC20, deployData);

        if (createdContract == expectedL2Address) {
            return false;
        } else {
            // trigger withdrawal then halt
            // this codepath should only be hit if the system is setup incorrectly
            // this withdrawal is for error recovery, not composing with L2 dapps, so we ignore the return value
            triggerWithdrawal(l1ERC20, address(this), _from, _amount, "");
            return true;
        }
    }
}
        

@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../math/SafeMathUpgradeable.sol";

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library CountersUpgradeable {
    using SafeMathUpgradeable for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        // The {SafeMath} overflow check can be skipped here, see the comment at the top
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}
          

Contract ABI

[{"type":"event","name":"DepositFinalized","inputs":[{"type":"address","name":"l1Token","internalType":"address","indexed":true},{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":true},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TxToL1","inputs":[{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":true},{"type":"uint256","name":"_id","internalType":"uint256","indexed":true},{"type":"bytes","name":"_data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"WithdrawalInitiated","inputs":[{"type":"address","name":"l1Token","internalType":"address","indexed":false},{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":true},{"type":"uint256","name":"_l2ToL1Id","internalType":"uint256","indexed":true},{"type":"uint256","name":"_exitNum","internalType":"uint256","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"beaconProxyFactory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"calculateL2TokenAddress","inputs":[{"type":"address","name":"l1ERC20","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"cloneableProxyHash","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"counterpartGateway","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"exitNum","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"finalizeInboundTransfer","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"outboundCalldata","internalType":"bytes"}],"name":"getOutboundCalldata","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getUserSalt","inputs":[{"type":"address","name":"l1ERC20","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_l1Counterpart","internalType":"address"},{"type":"address","name":"_router","internalType":"address"},{"type":"address","name":"_beaconProxyFactory","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"outboundTransfer","inputs":[{"type":"address","name":"_l1Token","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bytes","name":"res","internalType":"bytes"}],"name":"outboundTransfer","inputs":[{"type":"address","name":"_l1Token","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"postUpgradeInit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"router","inputs":[]}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b50611656806100206000396000f3fe6080604052600436106100b25760003560e01c806397881f8d1161006f57806397881f8d146102f2578063a0c76a9614610307578063a7e28d48146103e0578063c05e6a9514610413578063c0c53b8b14610428578063d2ce7d651461046d578063f887ea4014610507576100b2565b8063015234ab146100b75780632db09c1c146100de5780632e567b361461010f578063569f26ff146101a75780637b3a3c8b146101da57806395fcea78146102dd575b600080fd5b3480156100c357600080fd5b506100cc61051c565b60408051918252519081900360200190f35b3480156100ea57600080fd5b506100f3610522565b604080516001600160a01b039092168252519081900360200190f35b6101a5600480360360a081101561012557600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561016757600080fd5b82018360208201111561017957600080fd5b803590602001918460018302840111600160201b8311171561019a57600080fd5b509092509050610531565b005b3480156101b357600080fd5b506100cc600480360360208110156101ca57600080fd5b50356001600160a01b03166107d0565b610268600480360360808110156101f057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561022a57600080fd5b82018360208201111561023c57600080fd5b803590602001918460018302840111600160201b8311171561025d57600080fd5b509092509050610800565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102a257818101518382015260200161028a565b50505050905090810190601f1680156102cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102e957600080fd5b506101a561081c565b3480156102fe57600080fd5b506100cc610879565b34801561031357600080fd5b50610268600480360360a081101561032a57600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561036c57600080fd5b82018360208201111561037e57600080fd5b803590602001918460018302840111600160201b8311171561039f57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108ef945050505050565b3480156103ec57600080fd5b506100f36004803603602081101561040357600080fd5b50356001600160a01b03166109e7565b34801561041f57600080fd5b506100f3610a84565b34801561043457600080fd5b506101a56004803603606081101561044b57600080fd5b506001600160a01b038135811691602081013582169160409091013516610a93565b610268600480360360c081101561048357600080fd5b6001600160a01b0382358116926020810135909116916040820135916060810135916080820135919081019060c0810160a0820135600160201b8111156104c957600080fd5b8201836020820111156104db57600080fd5b803590602001918460018302840111600160201b831117156104fc57600080fd5b509092509050610b0d565b34801561051357600080fd5b506100f3610d67565b60025481565b6000546001600160a01b031681565b600054610546906001600160a01b0316610d76565b6001600160a01b0316336001600160a01b0316146105a6576040805162461bcd60e51b81526020600482015260186024820152774f4e4c595f434f554e544552504152545f4741544557415960401b604482015290519081900360640190fd5b6060806105b38484610d84565b9150915080516000146105d157506040805160208101909152600081525b60006105dc896109e7565b90506105f0816001600160a01b0316610eae565b6106175760006106048a838b8b8b89610eb4565b9050801561061557505050506107c8565b505b60408051600481526024810182526020810180516001600160e01b031663c2eeeebd60e01b178152915181516000936060936001600160a01b038716939092909182918083835b6020831061067d5780518252601f19909201916020918201910161065e565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146106dd576040519150601f19603f3d011682016040523d82523d6000602084013e6106e2565b606091505b509150915060008215806106f7575060208251105b1561070457506001610733565b600061071183600c611060565b90508c6001600160a01b0316816001600160a01b03161461073157600191505b505b8015610761576107558c308d8c604051806020016040528060008152506110c0565b505050505050506107c8565b50505061076f818888611140565b866001600160a01b0316886001600160a01b03168a6001600160a01b03167fc7f2e9c55c40a50fbc217dfc70cd39a222940dfa62145aa0ca49eb9535d4fcb2896040518082815260200191505060405180910390a45050505b505050505050565b604080516001600160a01b0383166020808301919091528251808303820181529183019092528051910120919050565b60606108128686866000808888610b0d565b9695505050505050565b60006108266111bd565b9050336001600160a01b03821614610876576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa32927a6afa0a226a4a760911b604482015290519081900360640190fd5b50565b600354604080516397881f8d60e01b815290516000926001600160a01b0316916397881f8d916004808301926020929190829003018186803b1580156108be57600080fd5b505afa1580156108d2573d6000803e3d6000fd5b505050506040513d60208110156108e857600080fd5b5051905090565b6060632e567b3660e01b86868686610909600254886111e2565b6040516001600160a01b0380871660248301908152868216604484015290851660648301526084820184905260a060a48301908152835160c484015283519192909160e490910190602085019080838360005b8381101561097457818101518382015260200161095c565b50505050905090810190601f1680156109a15780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909a16999099179098525095965050505050505095945050505050565b6003546000906001600160a01b031663e75b214130610a05856107d0565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d6020811015610a7c57600080fd5b505192915050565b6003546001600160a01b031681565b610a9d8383611275565b6001600160a01b038116610ae9576040805162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa122a0a1a7a760911b604482015290519081900360640190fd5b600380546001600160a01b0319166001600160a01b03929092169190911790555050565b60603415610b4d576040805162461bcd60e51b81526020600482015260086024820152674e4f5f56414c554560c01b604482015290519081900360640190fd5b60006060610b5a336112cb565b15610b7357610b6985856112df565b9092509050610bb0565b33915084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b805115610bfa576040805162461bcd60e51b8152602060048201526013602482015272115615149057d110551057d11254d050931151606a1b604482015290519081900360640190fd5b600080610c068c6109e7565b9050610c1a816001600160a01b0316610eae565b610c60576040805162461bcd60e51b81526020600482015260126024820152711513d2d15397d393d517d111541313d6515160721b604482015290519081900360640190fd5b8b6001600160a01b0316816001600160a01b031663c2eeeebd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ca357600080fd5b505afa158015610cb7573d6000803e3d6000fd5b505050506040513d6020811015610ccd57600080fd5b50516001600160a01b031614610d22576040805162461bcd60e51b81526020600482015260156024820152742727aa2fa2ac2822a1aa22a22fa618afaa27a5a2a760591b604482015290519081900360640190fd5b610d2d81858c61131d565b9950610d3c8c858d8d876110c0565b6040805160208082019390935281518082039093018352810190529c9b505050505050505050505050565b6001546001600160a01b031681565b61111161111160901b010190565b60608083836040811015610d9757600080fd5b810190602081018135600160201b811115610db157600080fd5b820183602082011115610dc357600080fd5b803590602001918460018302840111600160201b83111715610de457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610e3657600080fd5b820183602082011115610e4857600080fd5b803590602001918460018302840111600160201b83111715610e6957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250969b929a509198505050505050505050565b3b151590565b600080610ec0886107d0565b600354604080516329a5c5cf60e01b81526004810184905290519293506000926001600160a01b03909216916329a5c5cf9160248082019260209290919082900301818787803b158015610f1357600080fd5b505af1158015610f27573d6000803e3d6000fd5b505050506040513d6020811015610f3d57600080fd5b505160408051630c4edbe960e11b81526001600160a01b038c811660048301908152602483019384528851604484015288519495509085169363189db7d2938e938a9392606490910190602085019080838360005b83811015610faa578181015183820152602001610f92565b50505050905090810190601f168015610fd75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610ff757600080fd5b505af115801561100b573d6000803e3d6000fd5b50505050876001600160a01b0316816001600160a01b0316141561103457600092505050610812565b61105089308988604051806020016040528060008152506110c0565b5060019998505050505050505050565b600081601401835110156110b0576040805162461bcd60e51b815260206004820152601260248201527152656164206f7574206f6620626f756e647360701b604482015290519081900360640190fd5b500160200151600160601b900490565b600254600090816110de87866110d98b838b848b6108ef565b61138f565b604080516001600160a01b038b811682526020820186905281830189905291519293508392828a16928b16917f3073a74ecb728d10be779fe19a74a1428e20468f5b4d167bf9c73d9067847d73919081900360600190a4979650505050505050565b826001600160a01b0316638c2a993e83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156111a057600080fd5b505af11580156111b4573d6000803e3d6000fd5b50505050505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b606082826040516020018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561122c578181015183820152602001611214565b50505050905090810190601f1680156112595780820380516001836020036101000a031916815260200191505b5060408051601f19818403018152919052979650505050505050565b61127f82826113bb565b6001600160a01b0381166112c7576040805162461bcd60e51b815260206004820152600a6024820152692120a22fa927aaaa22a960b11b604482015290519081900360640190fd5b5050565b6001546001600160a01b0390811691161490565b60006060838360408110156112f357600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610e3657600080fd5b604080516374f4f54760e01b81526001600160a01b0384811660048301526024820184905291516000928616916374f4f547916044808301928692919082900301818387803b15801561136f57600080fd5b505af1158015611383573d6000803e3d6000fd5b50939695505050505050565b600280546001019055600080546113b390829086906001600160a01b031685611487565b949350505050565b6001600160a01b03821661140c576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d0d3d55395115494105495606a1b604482015290519081900360640190fd5b6000546001600160a01b031615611459576040805162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b604482015290519081900360640190fd5b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b604080516349460b4d60e11b81526001600160a01b0384166004820190815260248201928352835160448301528351600093849360649363928c169a938b938a938a93929088019060208501908083838d5b838110156114f15781810151838201526020016114d9565b50505050905090810190601f16801561151e5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b15801561153d57600080fd5b505af1158015611551573d6000803e3d6000fd5b50505050506040513d602081101561156857600080fd5b5051604080516020808252865182820152865193945084936001600160a01b03808a1694908b16937f2b986d32a0536b7e19baa48ab949fec7b903b7fad7730820b20632d100cc3a68938a93919283929083019185019080838360005b838110156115dd5781810151838201526020016115c5565b50505050905090810190601f16801561160a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a49594505050505056fea2646970667358221220ea0c4544dfe6a6bd643919157633fce33284fdacf56ea3d118e096cc71fd320364736f6c634300060b0033

Deployed ByteCode

0x6080604052600436106100b25760003560e01c806397881f8d1161006f57806397881f8d146102f2578063a0c76a9614610307578063a7e28d48146103e0578063c05e6a9514610413578063c0c53b8b14610428578063d2ce7d651461046d578063f887ea4014610507576100b2565b8063015234ab146100b75780632db09c1c146100de5780632e567b361461010f578063569f26ff146101a75780637b3a3c8b146101da57806395fcea78146102dd575b600080fd5b3480156100c357600080fd5b506100cc61051c565b60408051918252519081900360200190f35b3480156100ea57600080fd5b506100f3610522565b604080516001600160a01b039092168252519081900360200190f35b6101a5600480360360a081101561012557600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561016757600080fd5b82018360208201111561017957600080fd5b803590602001918460018302840111600160201b8311171561019a57600080fd5b509092509050610531565b005b3480156101b357600080fd5b506100cc600480360360208110156101ca57600080fd5b50356001600160a01b03166107d0565b610268600480360360808110156101f057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561022a57600080fd5b82018360208201111561023c57600080fd5b803590602001918460018302840111600160201b8311171561025d57600080fd5b509092509050610800565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102a257818101518382015260200161028a565b50505050905090810190601f1680156102cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102e957600080fd5b506101a561081c565b3480156102fe57600080fd5b506100cc610879565b34801561031357600080fd5b50610268600480360360a081101561032a57600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561036c57600080fd5b82018360208201111561037e57600080fd5b803590602001918460018302840111600160201b8311171561039f57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506108ef945050505050565b3480156103ec57600080fd5b506100f36004803603602081101561040357600080fd5b50356001600160a01b03166109e7565b34801561041f57600080fd5b506100f3610a84565b34801561043457600080fd5b506101a56004803603606081101561044b57600080fd5b506001600160a01b038135811691602081013582169160409091013516610a93565b610268600480360360c081101561048357600080fd5b6001600160a01b0382358116926020810135909116916040820135916060810135916080820135919081019060c0810160a0820135600160201b8111156104c957600080fd5b8201836020820111156104db57600080fd5b803590602001918460018302840111600160201b831117156104fc57600080fd5b509092509050610b0d565b34801561051357600080fd5b506100f3610d67565b60025481565b6000546001600160a01b031681565b600054610546906001600160a01b0316610d76565b6001600160a01b0316336001600160a01b0316146105a6576040805162461bcd60e51b81526020600482015260186024820152774f4e4c595f434f554e544552504152545f4741544557415960401b604482015290519081900360640190fd5b6060806105b38484610d84565b9150915080516000146105d157506040805160208101909152600081525b60006105dc896109e7565b90506105f0816001600160a01b0316610eae565b6106175760006106048a838b8b8b89610eb4565b9050801561061557505050506107c8565b505b60408051600481526024810182526020810180516001600160e01b031663c2eeeebd60e01b178152915181516000936060936001600160a01b038716939092909182918083835b6020831061067d5780518252601f19909201916020918201910161065e565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146106dd576040519150601f19603f3d011682016040523d82523d6000602084013e6106e2565b606091505b509150915060008215806106f7575060208251105b1561070457506001610733565b600061071183600c611060565b90508c6001600160a01b0316816001600160a01b03161461073157600191505b505b8015610761576107558c308d8c604051806020016040528060008152506110c0565b505050505050506107c8565b50505061076f818888611140565b866001600160a01b0316886001600160a01b03168a6001600160a01b03167fc7f2e9c55c40a50fbc217dfc70cd39a222940dfa62145aa0ca49eb9535d4fcb2896040518082815260200191505060405180910390a45050505b505050505050565b604080516001600160a01b0383166020808301919091528251808303820181529183019092528051910120919050565b60606108128686866000808888610b0d565b9695505050505050565b60006108266111bd565b9050336001600160a01b03821614610876576040805162461bcd60e51b815260206004820152600e60248201526d2727aa2fa32927a6afa0a226a4a760911b604482015290519081900360640190fd5b50565b600354604080516397881f8d60e01b815290516000926001600160a01b0316916397881f8d916004808301926020929190829003018186803b1580156108be57600080fd5b505afa1580156108d2573d6000803e3d6000fd5b505050506040513d60208110156108e857600080fd5b5051905090565b6060632e567b3660e01b86868686610909600254886111e2565b6040516001600160a01b0380871660248301908152868216604484015290851660648301526084820184905260a060a48301908152835160c484015283519192909160e490910190602085019080838360005b8381101561097457818101518382015260200161095c565b50505050905090810190601f1680156109a15780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909a16999099179098525095965050505050505095945050505050565b6003546000906001600160a01b031663e75b214130610a05856107d0565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b158015610a5257600080fd5b505afa158015610a66573d6000803e3d6000fd5b505050506040513d6020811015610a7c57600080fd5b505192915050565b6003546001600160a01b031681565b610a9d8383611275565b6001600160a01b038116610ae9576040805162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa122a0a1a7a760911b604482015290519081900360640190fd5b600380546001600160a01b0319166001600160a01b03929092169190911790555050565b60603415610b4d576040805162461bcd60e51b81526020600482015260086024820152674e4f5f56414c554560c01b604482015290519081900360640190fd5b60006060610b5a336112cb565b15610b7357610b6985856112df565b9092509050610bb0565b33915084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293505050505b805115610bfa576040805162461bcd60e51b8152602060048201526013602482015272115615149057d110551057d11254d050931151606a1b604482015290519081900360640190fd5b600080610c068c6109e7565b9050610c1a816001600160a01b0316610eae565b610c60576040805162461bcd60e51b81526020600482015260126024820152711513d2d15397d393d517d111541313d6515160721b604482015290519081900360640190fd5b8b6001600160a01b0316816001600160a01b031663c2eeeebd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ca357600080fd5b505afa158015610cb7573d6000803e3d6000fd5b505050506040513d6020811015610ccd57600080fd5b50516001600160a01b031614610d22576040805162461bcd60e51b81526020600482015260156024820152742727aa2fa2ac2822a1aa22a22fa618afaa27a5a2a760591b604482015290519081900360640190fd5b610d2d81858c61131d565b9950610d3c8c858d8d876110c0565b6040805160208082019390935281518082039093018352810190529c9b505050505050505050505050565b6001546001600160a01b031681565b61111161111160901b010190565b60608083836040811015610d9757600080fd5b810190602081018135600160201b811115610db157600080fd5b820183602082011115610dc357600080fd5b803590602001918460018302840111600160201b83111715610de457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610e3657600080fd5b820183602082011115610e4857600080fd5b803590602001918460018302840111600160201b83111715610e6957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250969b929a509198505050505050505050565b3b151590565b600080610ec0886107d0565b600354604080516329a5c5cf60e01b81526004810184905290519293506000926001600160a01b03909216916329a5c5cf9160248082019260209290919082900301818787803b158015610f1357600080fd5b505af1158015610f27573d6000803e3d6000fd5b505050506040513d6020811015610f3d57600080fd5b505160408051630c4edbe960e11b81526001600160a01b038c811660048301908152602483019384528851604484015288519495509085169363189db7d2938e938a9392606490910190602085019080838360005b83811015610faa578181015183820152602001610f92565b50505050905090810190601f168015610fd75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610ff757600080fd5b505af115801561100b573d6000803e3d6000fd5b50505050876001600160a01b0316816001600160a01b0316141561103457600092505050610812565b61105089308988604051806020016040528060008152506110c0565b5060019998505050505050505050565b600081601401835110156110b0576040805162461bcd60e51b815260206004820152601260248201527152656164206f7574206f6620626f756e647360701b604482015290519081900360640190fd5b500160200151600160601b900490565b600254600090816110de87866110d98b838b848b6108ef565b61138f565b604080516001600160a01b038b811682526020820186905281830189905291519293508392828a16928b16917f3073a74ecb728d10be779fe19a74a1428e20468f5b4d167bf9c73d9067847d73919081900360600190a4979650505050505050565b826001600160a01b0316638c2a993e83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156111a057600080fd5b505af11580156111b4573d6000803e3d6000fd5b50505050505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b606082826040516020018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561122c578181015183820152602001611214565b50505050905090810190601f1680156112595780820380516001836020036101000a031916815260200191505b5060408051601f19818403018152919052979650505050505050565b61127f82826113bb565b6001600160a01b0381166112c7576040805162461bcd60e51b815260206004820152600a6024820152692120a22fa927aaaa22a960b11b604482015290519081900360640190fd5b5050565b6001546001600160a01b0390811691161490565b60006060838360408110156112f357600080fd5b6001600160a01b038235169190810190604081016020820135600160201b811115610e3657600080fd5b604080516374f4f54760e01b81526001600160a01b0384811660048301526024820184905291516000928616916374f4f547916044808301928692919082900301818387803b15801561136f57600080fd5b505af1158015611383573d6000803e3d6000fd5b50939695505050505050565b600280546001019055600080546113b390829086906001600160a01b031685611487565b949350505050565b6001600160a01b03821661140c576040805162461bcd60e51b81526020600482015260136024820152721253959053125117d0d3d55395115494105495606a1b604482015290519081900360640190fd5b6000546001600160a01b031615611459576040805162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b604482015290519081900360640190fd5b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055565b604080516349460b4d60e11b81526001600160a01b0384166004820190815260248201928352835160448301528351600093849360649363928c169a938b938a938a93929088019060208501908083838d5b838110156114f15781810151838201526020016114d9565b50505050905090810190601f16801561151e5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b15801561153d57600080fd5b505af1158015611551573d6000803e3d6000fd5b50505050506040513d602081101561156857600080fd5b5051604080516020808252865182820152865193945084936001600160a01b03808a1694908b16937f2b986d32a0536b7e19baa48ab949fec7b903b7fad7730820b20632d100cc3a68938a93919283929083019185019080838360005b838110156115dd5781810151838201526020016115c5565b50505050905090810190601f16801561160a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a49594505050505056fea2646970667358221220ea0c4544dfe6a6bd643919157633fce33284fdacf56ea3d118e096cc71fd320364736f6c634300060b0033