false
false
0

Contract Address Details

0xb068C7a7ebE619ddb57bF0b05163511950F2140A

Contract Name
MultisigWallet
Creator
0xc7d98c–7f3521 at 0xbc2625–f2ce33
Balance
0.526769829903937742 CLO
Tokens
Fetching tokens...
Transactions
57 Transactions
Transfers
519 Transfers
Gas Used
2,435,723
Last Balance Update
16285227
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
MultisigWallet




Optimization enabled
true
Compiler version
v0.8.7+commit.e28d00a7




Optimization runs
200
EVM Version
default




Verified at
2024-09-26T15:33:23.871909Z

Constructor Arguments

0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000056d0be152490d5797416d8073d3850855b2fca3c0000000000000000000000004cc3a18209517a09f472639551357db80a17412b000000000000000000000000c9bea9379a8fade01240ee583535fac713b7101400000000000000000000000050016fe5de82d818ab8190b2e32115cae7c0cbf5000000000000000000000000600360f031a22213522329c41ead9f0a4d6f37ff
              

Contract source code

// SPDX-License-Identifier: No License (None)
pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256`
 * (`UintSet`) are supported.
 */
library EnumerableSet {

    struct AddressSet {
        // Storage of set values
        address[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (address => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        if (!contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            address lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns 1-based index of value in the set. O(1).
     */
    function indexOf(AddressSet storage set, address value) internal view returns (uint256) {
        return set._indexes[value];
    }


    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }
}

contract MultisigWallet {
    using EnumerableSet for EnumerableSet.AddressSet;
    struct Ballot {
        uint128 votes;      // bitmap of unique votes (max 127 votes)
        uint64 expire;      // time when ballot expire
        uint8 yea;          // number of votes `Yea`
    }

    EnumerableSet.AddressSet owners; // founders may transfer contract's ownership
    uint256 public ownersSetCounter;   // each time when change owners increase the counter
    uint256 public expirePeriod = 3 days;
    mapping(bytes32 => Ballot) public ballots;
 
    event SetOwner(address owner, bool isEnable);
    event CreateBallot(bytes32 ballotHash, uint256 expired);
    event Execute(bytes32 ballotHash, address to, uint256 value, bytes data);


    modifier onlyThis() {
        require(address(this) == msg.sender, "Only multisig allowed");
        _;
    }
    
    constructor (address[] memory _owners) {
        for (uint i = 0; i < _owners.length; i++) {
            require(_owners[i] != address(0), "Zero address");
            owners.add(_owners[i]);
        }
    }

    // get number of owners
    function getOwnersNumber() external view returns(uint256) {
        return owners.length();
    }

    // returns list of owners addresses
    function getOwners() external view returns(address[] memory) {
        return owners._values;
    }

    // add owner
    function addOwner(address owner) external onlyThis{
        require(owner != address(0), "Zero address");
        require(owners.length() < 127, "Too many owners");
        require(owners.add(owner), "Owner already added");
        ownersSetCounter++; // change owners set
        emit SetOwner(owner, true);
    }

    // remove owner
    function removeOwner(address owner) external onlyThis{
        require(owners.length() > 1, "Remove all owners is not allowed");
        require(owners.remove(owner), "Owner does not exist");
        ownersSetCounter++; // change owners set
        emit SetOwner(owner, false);
    }
    
    function setExpirePeriod(uint256 period) external onlyThis {
        require(period >= 1 days, "Too short period");  // avoid deadlock in case of set too short period
        expirePeriod = period;
    }

    function vote(address to, uint256 value, bytes calldata data) external {
        uint256 index = owners.indexOf(msg.sender);
        require(index != 0, "Only owner");
        bytes32 ballotHash = keccak256(abi.encodePacked(to, value, data, ownersSetCounter));
        Ballot memory b = ballots[ballotHash];
        if (b.expire == 0 || b.expire < uint64(block.timestamp)) { // if no ballot or ballot expired - create new ballot
            b.expire = uint64(block.timestamp + expirePeriod);
            b.votes = 0;
            b.yea = 0;
            emit CreateBallot(ballotHash, b.expire);
        }
        uint256 mask = 1 << index;
        if (b.votes & mask == 0) {  // this owner don't vote yet.
            b.votes = uint128(b.votes | mask); // record owner's vote
            b.yea += 1; // increase total votes "Yea"
        }

        if (b.yea >= owners.length() / 2 + 1) {   // vote "Yea" > 50% of owners
            delete ballots[ballotHash];
            execute(to, value, data);
            emit Execute(ballotHash, to, value, data);
        } else {
            // update ballot
            ballots[ballotHash] = b;
        }
    }

    function execute(address to, uint256 value, bytes memory data) internal {
        (bool success,) = to.call{value: value}(data);
        require(success, "Execute error");
    }

    // allow receive ERC223 tokens
    function tokenReceived(address _from, uint _value, bytes calldata _data) external {} 
    // allow receive coin
    receive() external payable {}
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address[]","name":"_owners","internalType":"address[]"}]},{"type":"event","name":"CreateBallot","inputs":[{"type":"bytes32","name":"ballotHash","internalType":"bytes32","indexed":false},{"type":"uint256","name":"expired","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Execute","inputs":[{"type":"bytes32","name":"ballotHash","internalType":"bytes32","indexed":false},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false},{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"SetOwner","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"bool","name":"isEnable","internalType":"bool","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"votes","internalType":"uint128"},{"type":"uint64","name":"expire","internalType":"uint64"},{"type":"uint8","name":"yea","internalType":"uint8"}],"name":"ballots","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"expirePeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getOwners","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getOwnersNumber","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"ownersSetCounter","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setExpirePeriod","inputs":[{"type":"uint256","name":"period","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"tokenReceived","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"vote","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x60806040526203f4806003553480156200001857600080fd5b50604051620010b5380380620010b58339810160408190526200003b91620001a3565b60005b8151811015620001085760006001600160a01b0316828281518110620000685762000068620002a6565b60200260200101516001600160a01b03161415620000bb5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640160405180910390fd5b620000f2828281518110620000d457620000d4620002a6565b602002602001015160006200011060201b6200085e1790919060201c565b5080620000ff816200027c565b9150506200003e565b5050620002d2565b6001600160a01b03811660009081526001830160205260408120546200017c57508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b0386169081179091558554908252828601909352604090209190915562000180565b5060005b92915050565b80516001600160a01b03811681146200019e57600080fd5b919050565b60006020808385031215620001b757600080fd5b82516001600160401b0380821115620001cf57600080fd5b818501915085601f830112620001e457600080fd5b815181811115620001f957620001f9620002bc565b8060051b604051601f19603f83011681018181108582111715620002215762000221620002bc565b604052828152858101935084860182860187018a10156200024157600080fd5b600095505b838610156200026f576200025a8162000186565b85526001959095019493860193860162000246565b5098975050505050505050565b60006000198214156200029f57634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610dd380620002e26000396000f3fe6080604052600436106100955760003560e01c80638638fb5a116100595780638638fb5a146101a757806386cbaed8146101bc5780638943ec02146101dc578063a0e67e2b146101fd578063d7a52fa91461021f57600080fd5b8063163d262f146100a1578063173825d9146100ca57806321407e53146100ec5780637065cb48146101025780637dd0dd161461012257600080fd5b3661009c57005b600080fd5b3480156100ad57600080fd5b506100b760025481565b6040519081526020015b60405180910390f35b3480156100d657600080fd5b506100ea6100e5366004610ace565b61023f565b005b3480156100f857600080fd5b506100b760035481565b34801561010e57600080fd5b506100ea61011d366004610ace565b610368565b34801561012e57600080fd5b5061017661013d366004610b77565b6004602052600090815260409020546001600160801b03811690600160801b810467ffffffffffffffff1690600160c01b900460ff1683565b604080516001600160801b03909416845267ffffffffffffffff909216602084015260ff16908201526060016100c1565b3480156101b357600080fd5b506000546100b7565b3480156101c857600080fd5b506100ea6101d7366004610af0565b6104b7565b3480156101e857600080fd5b506100ea6101f7366004610af0565b50505050565b34801561020957600080fd5b50610212610790565b6040516100c19190610bff565b34801561022b57600080fd5b506100ea61023a366004610b77565b6107f4565b3033146102675760405162461bcd60e51b815260040161025e90610c9b565b60405180910390fd5b600161027260005490565b116102bf5760405162461bcd60e51b815260206004820181905260248201527f52656d6f766520616c6c206f776e657273206973206e6f7420616c6c6f776564604482015260640161025e565b6102ca6000826108d2565b61030d5760405162461bcd60e51b815260206004820152601460248201527313dddb995c88191bd95cc81b9bdd08195e1a5cdd60621b604482015260640161025e565b6002805490600061031d83610d40565b9091555050604080516001600160a01b0383168152600060208201527f5501576e82029b0850ec7c74ac25b5a46839bf523772a6ac579cc55b092281c891015b60405180910390a150565b3033146103875760405162461bcd60e51b815260040161025e90610c9b565b6001600160a01b0381166103cc5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640161025e565b607f6103d760005490565b106104165760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206f776e65727360881b604482015260640161025e565b61042160008261085e565b6104635760405162461bcd60e51b815260206004820152601360248201527213dddb995c88185b1c9958591e481859191959606a1b604482015260640161025e565b6002805490600061047383610d40565b9091555050604080516001600160a01b0383168152600160208201527f5501576e82029b0850ec7c74ac25b5a46839bf523772a6ac579cc55b092281c8910161035d565b33600090815260016020526040902054806105015760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b604482015260640161025e565b60008585858560025460405160200161051e959493929190610b90565b60408051808303601f190181528282528051602091820120600081815260048352839020606085018452546001600160801b0381168552600160801b810467ffffffffffffffff16928501839052600160c01b900460ff169284019290925290925015806105a357504267ffffffffffffffff16816020015167ffffffffffffffff16105b1561060d576003546105b59042610cca565b67ffffffffffffffff16602082810182905260008084526040808501919091528051858152918201929092527fdba396e3f86ba92c12e944cda2d787eea52a24f6babcbd54c8ffb2d369bca7c9910160405180910390a15b80516001841b9081166001600160801b03166106515781516001600160801b0380831691161782526040820180516001919061064a908390610ce2565b60ff169052505b600261065c60005490565b6106669190610d07565b610671906001610cca565b826040015160ff16106107205760008381526004602090815260409182902080546001600160c81b03191690558151601f88018290048202810182019092528682526106dc918a918a91908a908a9081908401838280828437600092019190915250610a1492505050565b7fc75495e0be082158e5855c35d211235055bf668ec3933eb9f3cf757c6493ee6d8389898989604051610713959493929190610c4c565b60405180910390a1610786565b60008381526004602090815260409182902084518154928601519386015160ff16600160c01b0260ff60c01b1967ffffffffffffffff909516600160801b026001600160c01b03199094166001600160801b039092169190911792909217929092161790555b5050505050505050565b6060600080018054806020026020016040519081016040528092919081815260200182805480156107ea57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116107cc575b5050505050905090565b3033146108135760405162461bcd60e51b815260040161025e90610c9b565b620151808110156108595760405162461bcd60e51b815260206004820152601060248201526f151bdbc81cda1bdc9d081c195c9a5bd960821b604482015260640161025e565b600355565b6001600160a01b03811660009081526001830160205260408120546108c857508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b038616908117909155855490825282860190935260409020919091556108cc565b5060005b92915050565b6001600160a01b03811660009081526001830160205260408120548015610a0a576000610900600183610d29565b855490915060009061091490600190610d29565b9050600086600001828154811061092d5761092d610d87565b60009182526020909120015487546001600160a01b039091169150819088908590811061095c5761095c610d87565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055610990836001610cca565b6001600160a01b038216600090815260018901602052604090205586548790806109bc576109bc610d71565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03881682526001898101909152604082209190915594506108cc9350505050565b60009150506108cc565b6000836001600160a01b03168383604051610a2f9190610bc4565b60006040518083038185875af1925050503d8060008114610a6c576040519150601f19603f3d011682016040523d82523d6000602084013e610a71565b606091505b50509050806101f75760405162461bcd60e51b815260206004820152600d60248201526c22bc32b1baba329032b93937b960991b604482015260640161025e565b80356001600160a01b0381168114610ac957600080fd5b919050565b600060208284031215610ae057600080fd5b610ae982610ab2565b9392505050565b60008060008060608587031215610b0657600080fd5b610b0f85610ab2565b935060208501359250604085013567ffffffffffffffff80821115610b3357600080fd5b818701915087601f830112610b4757600080fd5b813581811115610b5657600080fd5b886020828501011115610b6857600080fd5b95989497505060200194505050565b600060208284031215610b8957600080fd5b5035919050565b6bffffffffffffffffffffffff198660601b1681528460148201528284603483013760349201918201526054019392505050565b6000825160005b81811015610be55760208186018101518583015201610bcb565b81811115610bf4576000828501525b509190910192915050565b6020808252825182820181905260009190848201906040850190845b81811015610c405783516001600160a01b031683529284019291840191600101610c1b565b50909695505050505050565b8581526001600160a01b0385166020820152604081018490526080606082018190528101829052818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60208082526015908201527413db9b1e481b5d5b1d1a5cda59c8185b1b1bddd959605a1b604082015260600190565b60008219821115610cdd57610cdd610d5b565b500190565b600060ff821660ff84168060ff03821115610cff57610cff610d5b565b019392505050565b600082610d2457634e487b7160e01b600052601260045260246000fd5b500490565b600082821015610d3b57610d3b610d5b565b500390565b6000600019821415610d5457610d54610d5b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220aad3c3f29f7041250296c4edb8359493edb807d1a8b59ddb64657e1c43effb4e64736f6c634300080700330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000056d0be152490d5797416d8073d3850855b2fca3c0000000000000000000000004cc3a18209517a09f472639551357db80a17412b000000000000000000000000c9bea9379a8fade01240ee583535fac713b7101400000000000000000000000050016fe5de82d818ab8190b2e32115cae7c0cbf5000000000000000000000000600360f031a22213522329c41ead9f0a4d6f37ff

Deployed ByteCode

0x6080604052600436106100955760003560e01c80638638fb5a116100595780638638fb5a146101a757806386cbaed8146101bc5780638943ec02146101dc578063a0e67e2b146101fd578063d7a52fa91461021f57600080fd5b8063163d262f146100a1578063173825d9146100ca57806321407e53146100ec5780637065cb48146101025780637dd0dd161461012257600080fd5b3661009c57005b600080fd5b3480156100ad57600080fd5b506100b760025481565b6040519081526020015b60405180910390f35b3480156100d657600080fd5b506100ea6100e5366004610ace565b61023f565b005b3480156100f857600080fd5b506100b760035481565b34801561010e57600080fd5b506100ea61011d366004610ace565b610368565b34801561012e57600080fd5b5061017661013d366004610b77565b6004602052600090815260409020546001600160801b03811690600160801b810467ffffffffffffffff1690600160c01b900460ff1683565b604080516001600160801b03909416845267ffffffffffffffff909216602084015260ff16908201526060016100c1565b3480156101b357600080fd5b506000546100b7565b3480156101c857600080fd5b506100ea6101d7366004610af0565b6104b7565b3480156101e857600080fd5b506100ea6101f7366004610af0565b50505050565b34801561020957600080fd5b50610212610790565b6040516100c19190610bff565b34801561022b57600080fd5b506100ea61023a366004610b77565b6107f4565b3033146102675760405162461bcd60e51b815260040161025e90610c9b565b60405180910390fd5b600161027260005490565b116102bf5760405162461bcd60e51b815260206004820181905260248201527f52656d6f766520616c6c206f776e657273206973206e6f7420616c6c6f776564604482015260640161025e565b6102ca6000826108d2565b61030d5760405162461bcd60e51b815260206004820152601460248201527313dddb995c88191bd95cc81b9bdd08195e1a5cdd60621b604482015260640161025e565b6002805490600061031d83610d40565b9091555050604080516001600160a01b0383168152600060208201527f5501576e82029b0850ec7c74ac25b5a46839bf523772a6ac579cc55b092281c891015b60405180910390a150565b3033146103875760405162461bcd60e51b815260040161025e90610c9b565b6001600160a01b0381166103cc5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640161025e565b607f6103d760005490565b106104165760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206f776e65727360881b604482015260640161025e565b61042160008261085e565b6104635760405162461bcd60e51b815260206004820152601360248201527213dddb995c88185b1c9958591e481859191959606a1b604482015260640161025e565b6002805490600061047383610d40565b9091555050604080516001600160a01b0383168152600160208201527f5501576e82029b0850ec7c74ac25b5a46839bf523772a6ac579cc55b092281c8910161035d565b33600090815260016020526040902054806105015760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b604482015260640161025e565b60008585858560025460405160200161051e959493929190610b90565b60408051808303601f190181528282528051602091820120600081815260048352839020606085018452546001600160801b0381168552600160801b810467ffffffffffffffff16928501839052600160c01b900460ff169284019290925290925015806105a357504267ffffffffffffffff16816020015167ffffffffffffffff16105b1561060d576003546105b59042610cca565b67ffffffffffffffff16602082810182905260008084526040808501919091528051858152918201929092527fdba396e3f86ba92c12e944cda2d787eea52a24f6babcbd54c8ffb2d369bca7c9910160405180910390a15b80516001841b9081166001600160801b03166106515781516001600160801b0380831691161782526040820180516001919061064a908390610ce2565b60ff169052505b600261065c60005490565b6106669190610d07565b610671906001610cca565b826040015160ff16106107205760008381526004602090815260409182902080546001600160c81b03191690558151601f88018290048202810182019092528682526106dc918a918a91908a908a9081908401838280828437600092019190915250610a1492505050565b7fc75495e0be082158e5855c35d211235055bf668ec3933eb9f3cf757c6493ee6d8389898989604051610713959493929190610c4c565b60405180910390a1610786565b60008381526004602090815260409182902084518154928601519386015160ff16600160c01b0260ff60c01b1967ffffffffffffffff909516600160801b026001600160c01b03199094166001600160801b039092169190911792909217929092161790555b5050505050505050565b6060600080018054806020026020016040519081016040528092919081815260200182805480156107ea57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116107cc575b5050505050905090565b3033146108135760405162461bcd60e51b815260040161025e90610c9b565b620151808110156108595760405162461bcd60e51b815260206004820152601060248201526f151bdbc81cda1bdc9d081c195c9a5bd960821b604482015260640161025e565b600355565b6001600160a01b03811660009081526001830160205260408120546108c857508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b038616908117909155855490825282860190935260409020919091556108cc565b5060005b92915050565b6001600160a01b03811660009081526001830160205260408120548015610a0a576000610900600183610d29565b855490915060009061091490600190610d29565b9050600086600001828154811061092d5761092d610d87565b60009182526020909120015487546001600160a01b039091169150819088908590811061095c5761095c610d87565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055610990836001610cca565b6001600160a01b038216600090815260018901602052604090205586548790806109bc576109bc610d71565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03881682526001898101909152604082209190915594506108cc9350505050565b60009150506108cc565b6000836001600160a01b03168383604051610a2f9190610bc4565b60006040518083038185875af1925050503d8060008114610a6c576040519150601f19603f3d011682016040523d82523d6000602084013e610a71565b606091505b50509050806101f75760405162461bcd60e51b815260206004820152600d60248201526c22bc32b1baba329032b93937b960991b604482015260640161025e565b80356001600160a01b0381168114610ac957600080fd5b919050565b600060208284031215610ae057600080fd5b610ae982610ab2565b9392505050565b60008060008060608587031215610b0657600080fd5b610b0f85610ab2565b935060208501359250604085013567ffffffffffffffff80821115610b3357600080fd5b818701915087601f830112610b4757600080fd5b813581811115610b5657600080fd5b886020828501011115610b6857600080fd5b95989497505060200194505050565b600060208284031215610b8957600080fd5b5035919050565b6bffffffffffffffffffffffff198660601b1681528460148201528284603483013760349201918201526054019392505050565b6000825160005b81811015610be55760208186018101518583015201610bcb565b81811115610bf4576000828501525b509190910192915050565b6020808252825182820181905260009190848201906040850190845b81811015610c405783516001600160a01b031683529284019291840191600101610c1b565b50909695505050505050565b8581526001600160a01b0385166020820152604081018490526080606082018190528101829052818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b60208082526015908201527413db9b1e481b5d5b1d1a5cda59c8185b1b1bddd959605a1b604082015260600190565b60008219821115610cdd57610cdd610d5b565b500190565b600060ff821660ff84168060ff03821115610cff57610cff610d5b565b019392505050565b600082610d2457634e487b7160e01b600052601260045260246000fd5b500490565b600082821015610d3b57610d3b610d5b565b500390565b6000600019821415610d5457610d54610d5b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220aad3c3f29f7041250296c4edb8359493edb807d1a8b59ddb64657e1c43effb4e64736f6c63430008070033