diff --git a/contracts/TokenManager.sol b/contracts/TokenManager.sol index f5ee402e..cc0a65aa 100644 --- a/contracts/TokenManager.sol +++ b/contracts/TokenManager.sol @@ -112,6 +112,7 @@ contract TokenManager is System, IApplication, IParamSubscriber { mapping(bytes32 => BindSynPackage) public bindPackageRecord; mapping(address => bool) public mirrorPendingRecord; + mapping(address => bool) public boundByMirror; uint256 public mirrorFee; uint256 public syncFee; @@ -201,6 +202,7 @@ contract TokenManager is System, IApplication, IParamSubscriber { } function approveBind(address contractAddr, string memory bep2Symbol) payable public returns (bool) { + require(!mirrorPendingRecord[contractAddr], "the bep20 token is in mirror pending status"); bytes32 bep2TokenSymbol = bep2TokenSymbolConvert(bep2Symbol); BindSynPackage memory bindSynPkg = bindPackageRecord[bep2TokenSymbol]; require(bindSynPkg.bep2TokenSymbol!=bytes32(0x00), "bind request doesn't exist"); @@ -232,7 +234,6 @@ contract TokenManager is System, IApplication, IParamSubscriber { } function rejectBind(address contractAddr, string memory bep2Symbol) payable public returns (bool) { - require(!mirrorPendingRecord[contractAddr], "the bep20 token is in mirror pending status"); bytes32 bep2TokenSymbol = bep2TokenSymbolConvert(bep2Symbol); BindSynPackage memory bindSynPkg = bindPackageRecord[bep2TokenSymbol]; require(bindSynPkg.bep2TokenSymbol!=bytes32(0x00), "bind request doesn't exist"); @@ -377,6 +378,7 @@ contract TokenManager is System, IApplication, IParamSubscriber { if (mirrorAckPackage.errorCode == MIRROR_STATUS_SUCCESS ) { address(uint160(TOKEN_HUB_ADDR)).transfer(mirrorAckPackage.mirrorFee); ITokenHub(TOKEN_HUB_ADDR).bindToken(mirrorAckPackage.bep2Symbol, mirrorAckPackage.bep20Addr, mirrorAckPackage.bep20Decimals); + boundByMirror[mirrorAckPackage.bep20Addr] = true; emit mirrorSuccess(mirrorAckPackage.bep20Addr, mirrorAckPackage.bep2Symbol); return; } else if (mirrorAckPackage.errorCode == MIRROR_STATUS_TIMEOUT ) { @@ -395,7 +397,7 @@ contract TokenManager is System, IApplication, IParamSubscriber { (MirrorSynPackage memory mirrorSynPackage, bool decodeSuccess) = decodeMirrorSynPackage(msgBytes); require(decodeSuccess, "unrecognized mirror syn package"); mirrorPendingRecord[mirrorSynPackage.bep20Addr] = false; - mirrorSynPackage.mirrorSender.call{gas: MAX_GAS_FOR_TRANSFER_BNB, value: mirrorSynPackage.mirrorFee}(""); + mirrorSynPackage.mirrorSender.call{gas: MAX_GAS_FOR_TRANSFER_BNB, value: mirrorSynPackage.mirrorFee*TEN_DECIMALS}(""); } function encodeSyncSynPackage(SyncSynPackage memory syncSynPackage) internal pure returns (bytes memory) { @@ -436,7 +438,7 @@ contract TokenManager is System, IApplication, IParamSubscriber { while (iter.hasNext()) { if (idx == 0) syncAckPackage.syncSender = iter.next().toAddress(); else if (idx == 1) syncAckPackage.bep20Addr = iter.next().toAddress(); - else if (idx == 2) syncAckPackage.syncFee = uint8(iter.next().toUint()); + else if (idx == 2) syncAckPackage.syncFee = iter.next().toUint(); else if (idx == 3) { syncAckPackage.errorCode = uint8(iter.next().toUint()); success = true; @@ -449,12 +451,13 @@ contract TokenManager is System, IApplication, IParamSubscriber { function sync(address bep20Addr, uint64 expireTime) payable public returns (bool) { require(ITokenHub(TOKEN_HUB_ADDR).getBep2SymbolByContractAddr(bep20Addr) != bytes32(0x00), "the bep20 token is not bound"); + require(boundByMirror[bep20Addr], "the bep20 token is not bound by mirror"); uint256 miniRelayFee = ITokenHub(TOKEN_HUB_ADDR).getMiniRelayFee(); require(msg.value%TEN_DECIMALS == 0 && msg.value>=syncFee.add(miniRelayFee), "msg.value must be N * 1e10 and greater than sum of miniRelayFee and syncFee"); require(expireTime>=block.timestamp + 120 && expireTime <= block.timestamp + 86400, "expireTime must be two minutes later and one day earlier"); uint256 totalSupply = IBEP20(bep20Addr).totalSupply(); uint8 decimals = IBEP20(bep20Addr).decimals(); - require(convertToBep2Amount(totalSupply, decimals) <= MAX_BEP2_TOTAL_SUPPLY, "bep20 total supply is to large"); + require(convertToBep2Amount(totalSupply, decimals) <= MAX_BEP2_TOTAL_SUPPLY, "bep20 total supply is too large"); address(uint160(TOKEN_HUB_ADDR)).transfer(msg.value.sub(syncFee)); SyncSynPackage memory syncSynPackage = SyncSynPackage({ @@ -488,7 +491,7 @@ contract TokenManager is System, IApplication, IParamSubscriber { function handleSyncFailAckPackage(bytes memory msgBytes) internal { (SyncSynPackage memory syncSynPackage, bool decodeSuccess) = decodeSyncSynPackage(msgBytes); require(decodeSuccess, "unrecognized sync syn package"); - syncSynPackage.syncSender.call{gas: MAX_GAS_FOR_TRANSFER_BNB, value: syncSynPackage.syncFee}(""); + syncSynPackage.syncSender.call{gas: MAX_GAS_FOR_TRANSFER_BNB, value: syncSynPackage.syncFee*TEN_DECIMALS}(""); } function updateParam(string calldata key, bytes calldata value) override external onlyGov{ diff --git a/genesis.json b/genesis.json index 75eba0b0..69d05b14 100644 --- a/genesis.json +++ b/genesis.json @@ -63,7 +63,7 @@ }, "0x0000000000000000000000000000000000001008": { "balance": "0x0", - "code": "0x60806040526004361061038c5760003560e01c80637942fd05116101dc578063b795031711610102578063dc927faf116100a0578063fa9e91591161006f578063fa9e915914610d10578063fc3e59081461059f578063fd6a687914610d25578063fe3a2af5146105575761038c565b8063dc927faf14610cd1578063e605bca014610ce6578063e80561fa14610557578063f9a2bbc714610cfb5761038c565b8063c8509d81116100dc578063c8509d8114610bcc578063c8e704a41461059f578063d117a11014610c51578063d9e6dae9146106e95761038c565b8063b795031714610728578063bd32d3f9146104e4578063c81b166214610bb75761038c565b806396713da91161017a578063a78abc1611610149578063a78abc1614610ac2578063ab51bb9614610ad7578063ab67a48514610728578063ac43175114610aec5761038c565b806396713da914610a6e5780639a854bbd14610a835780639dc0926214610a98578063a1a11bf514610aad5761038c565b8063831d65d1116101b6578063831d65d11461099d578063859180fb146106d457806394553a4e14610a2457806395b9ad2614610a595761038c565b80637942fd05146109735780637d078e13146104f95780637ec816dd146109885761038c565b8063493279b1116102c1578063613684751161025f57806370fd5bad1161022e57806370fd5bad1461072857806372c4e0861461080657806375d47a0a146108aa57806377d9dae8146108bf5761038c565b806361368475146106e957806366dea52a1461059f5780636b3f13071461073d5780636e47b482146107f15761038c565b80634bf6c8821161029b5780634bf6c882146106e957806351e80672146106fe5780635d499b1b146107135780635f558f86146107285761038c565b8063493279b1146106a85780634a688818146105575780634bc81c00146106d45761038c565b80632d89ac321161032e578063401809f911610308578063401809f91461059f57806343756e5c146105b4578063445fcefe146105e5578063487c88ac146104f95761038c565b80632d89ac32146104f957806337e6ecda1461056c5780633dffc387146104f95761038c565b80631f91600b1161036a5780631f91600b146104e457806323996b53146104f957806325c751b71461050e57806328ae4862146105575761038c565b80630bee7a67146103915780630f212b1b146103bf5780631182b875146103ea575b600080fd5b34801561039d57600080fd5b506103a6610d3a565b6040805163ffffffff9092168252519081900360200190f35b3480156103cb57600080fd5b506103d4610d3f565b6040805160ff9092168252519081900360200190f35b3480156103f657600080fd5b5061046f6004803603604081101561040d57600080fd5b60ff8235169190810190604081016020820135600160201b81111561043157600080fd5b82018360208201111561044357600080fd5b803590602001918460018302840111600160201b8311171561046457600080fd5b509092509050610d44565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104a9578181015183820152602001610491565b50505050905090810190601f1680156104d65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104f057600080fd5b506103d4610e5e565b34801561050557600080fd5b506103d4610e63565b6105436004803603604081101561052457600080fd5b5080356001600160a01b031690602001356001600160401b0316610e68565b604080519115158252519081900360200190f35b34801561056357600080fd5b506103d461135b565b34801561057857600080fd5b506105436004803603602081101561058f57600080fd5b50356001600160a01b0316611360565b3480156105ab57600080fd5b506103d4611375565b3480156105c057600080fd5b506105c961137a565b604080516001600160a01b039092168252519081900360200190f35b3480156105f157600080fd5b506106966004803603602081101561060857600080fd5b810190602081018135600160201b81111561062257600080fd5b82018360208201111561063457600080fd5b803590602001918460018302840111600160201b8311171561065557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611380945050505050565b60408051918252519081900360200190f35b3480156106b457600080fd5b506106bd6114de565b6040805161ffff9092168252519081900360200190f35b3480156106e057600080fd5b506103d46114e3565b3480156106f557600080fd5b506103d46114e8565b34801561070a57600080fd5b506105c96114ed565b34801561071f57600080fd5b506106966114f3565b34801561073457600080fd5b506103d46114fc565b6105436004803603604081101561075357600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561077d57600080fd5b82018360208201111561078f57600080fd5b803590602001918460018302840111600160201b831117156107b057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611501945050505050565b3480156107fd57600080fd5b506105c9611d80565b6105436004803603602081101561081c57600080fd5b810190602081018135600160201b81111561083657600080fd5b82018360208201111561084857600080fd5b803590602001918460018302840111600160201b8311171561086957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611d86945050505050565b3480156108b657600080fd5b506105c96121d2565b610543600480360360408110156108d557600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156108ff57600080fd5b82018360208201111561091157600080fd5b803590602001918460018302840111600160201b8311171561093257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506121d8945050505050565b34801561097f57600080fd5b506103d4612735565b34801561099457600080fd5b5061069661273a565b3480156109a957600080fd5b50610a22600480360360408110156109c057600080fd5b60ff8235169190810190604081016020820135600160201b8111156109e457600080fd5b8201836020820111156109f657600080fd5b803590602001918460018302840111600160201b83111715610a1757600080fd5b509092509050612740565b005b61054360048036036040811015610a3a57600080fd5b5080356001600160a01b031690602001356001600160401b031661288f565b348015610a6557600080fd5b506103d46131f3565b348015610a7a57600080fd5b506103d46131f8565b348015610a8f57600080fd5b506106966131fd565b348015610aa457600080fd5b506105c9613209565b348015610ab957600080fd5b506105c961320f565b348015610ace57600080fd5b50610543613215565b348015610ae357600080fd5b506103a661135b565b348015610af857600080fd5b50610a2260048036036040811015610b0f57600080fd5b810190602081018135600160201b811115610b2957600080fd5b820183602082011115610b3b57600080fd5b803590602001918460018302840111600160201b83111715610b5c57600080fd5b919390929091602081019035600160201b811115610b7957600080fd5b820183602082011115610b8b57600080fd5b803590602001918460018302840111600160201b83111715610bac57600080fd5b50909250905061321e565b348015610bc357600080fd5b506105c96134dd565b348015610bd857600080fd5b50610a2260048036036040811015610bef57600080fd5b60ff8235169190810190604081016020820135600160201b811115610c1357600080fd5b820183602082011115610c2557600080fd5b803590602001918460018302840111600160201b83111715610c4657600080fd5b5090925090506134e3565b348015610c5d57600080fd5b50610c7b60048036036020811015610c7457600080fd5b50356135b9565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a08301526001600160401b0390921660c082015290519081900360e00190f35b348015610cdd57600080fd5b506105c9613610565b348015610cf257600080fd5b50610696613616565b348015610d0757600080fd5b506105c961361c565b348015610d1c57600080fd5b50610696613622565b348015610d3157600080fd5b506105c9613628565b606481565b600681565b60603361200014610d865760405162461bcd60e51b815260040180806020018281038252602f815260200180615b8f602f913960400191505060405180910390fd5b60ff841660011415610dd857610dd183838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061362e92505050565b9050610e57565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605848484604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1506040805160008152602081019091525b9392505050565b600481565b600181565b6040805163bd46646160e01b81526001600160a01b0384166004820152905160009182916110049163bd466461916024808301926020929190829003018186803b158015610eb557600080fd5b505afa158015610ec9573d6000803e3d6000fd5b505050506040513d6020811015610edf57600080fd5b50511415610f34576040805162461bcd60e51b815260206004820152601c60248201527f74686520626570323020746f6b656e206973206e6f7420626f756e6400000000604482015290519081900360640190fd5b60006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610f7157600080fd5b505afa158015610f85573d6000803e3d6000fd5b505050506040513d6020811015610f9b57600080fd5b505190506402540be4003406158015610fc65750600454610fc2908263ffffffff6138be16565b3410155b6110015760405162461bcd60e51b815260040180806020018281038252604b815260200180615a1b604b913960600191505060405180910390fd5b42607801836001600160401b03161015801561102b5750426201518001836001600160401b031611155b6110665760405162461bcd60e51b81526004018080602001828103825260388152602001806159ac6038913960400191505060405180910390fd5b6000846001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110a157600080fd5b505afa1580156110b5573d6000803e3d6000fd5b505050506040513d60208110156110cb57600080fd5b50516040805163313ce56760e01b815290519192506000916001600160a01b0388169163313ce567916004808301926020929190829003018186803b15801561111357600080fd5b505afa158015611127573d6000803e3d6000fd5b505050506040513d602081101561113d57600080fd5b50519050677ce66c50e28400006111578360ff8416613918565b11156111aa576040805162461bcd60e51b815260206004820152601e60248201527f626570323020746f74616c20737570706c7920697320746f206c617267650000604482015290519081900360640190fd5b600454611004906108fc906111c690349063ffffffff61395816565b6040518115909202916000818181858888f193505050501580156111ee573d6000803e3d6000fd5b506111f76157af565b6040518060a00160405280336001600160a01b03168152602001886001600160a01b031681526020018481526020016402540be4006004548161123657fe5b0481526001600160401b038816602090910152905061200063f7a251d7600561125e8461399a565b6112886402540be40061127c6004543461395890919063ffffffff16565b9063ffffffff613aa716565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156112e65781810151838201526020016112ce565b50505050905090810190601f1680156113135780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561133457600080fd5b505af1158015611348573d6000803e3d6000fd5b5050505060019450505050505b92915050565b600081565b60026020526000908152604090205460ff1681565b600381565b61100181565b60208101516000906113906157dd565b50600081815260016020818152604092839020835160e081018552815460ff9081168252938201549281019290925260028101546001600160a01b031693820184905260038101546060830152600481015460808301526005015491821660a08201526101009091046001600160401b031660c082015290611417576000925050506114d9565b600081604001516001600160a01b03166370a082316110046040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561147557600080fd5b505afa158015611489573d6000803e3d6000fd5b505050506040513d602081101561149f57600080fd5b5051608083015160608401519192506000916114c09163ffffffff61395816565b90506114d2818363ffffffff61395816565b9450505050505b919050565b606081565b600581565b600881565b61200081565b6402540be40081565b600281565b60008061150d83613ae9565b90506115176157dd565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a08401526101009091046001600160401b031660c08301526115dc576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b60006115f98260800151836060015161395890919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b03161461164f5760405162461bcd60e51b8152600401808060200182810382526045815260200180615a666045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b15801561169257600080fd5b505afa1580156116a6573d6000803e3d6000fd5b505050506040513d60208110156116bc57600080fd5b50516001600160a01b0316146117035760405162461bcd60e51b815260040180806020018281038252602e81526020018061597e602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b15801561174f57600080fd5b505afa158015611763573d6000803e3d6000fd5b505050506040513d602081101561177957600080fd5b505160408051636eb1769f60e11b81523360048201523060248201529051919250839161180a9184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b1580156117d257600080fd5b505afa1580156117e6573d6000803e3d6000fd5b505050506040513d60208110156117fc57600080fd5b50519063ffffffff6138be16565b101561185d576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561189f57600080fd5b505afa1580156118b3573d6000803e3d6000fd5b505050506040513d60208110156118c957600080fd5b505190508082108015906118e257506402540be4008206155b61191d5760405162461bcd60e51b81526004018080602001828103825260378152602001806159e46037913960400191505060405180910390fd5b6000611929868b613af0565b905063ffffffff8116611b28576001600160a01b038a166323b872dd33611004611959898963ffffffff61395816565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156119c157600080fd5b505af11580156119d5573d6000803e3d6000fd5b505050506040513d60208110156119eb57600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b158015611a5457600080fd5b505af1158015611a68573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015611ae7578181015183820152602001611acf565b50505050905090810190601f168015611b145780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2611be0565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611ba4578181015183820152602001611b8c565b50505050905090810190601f168015611bd15780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055611c3a615819565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f19350505050158015611c82573d6000803e3d6000fd5b5061200063f7a251d76001611c9684613f4a565b611cab886402540be40063ffffffff613aa716565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611d09578181015183820152602001611cf1565b50505050905090810190601f168015611d365780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d5757600080fd5b505af1158015611d6b573d6000803e3d6000fd5b5060019e9d5050505050505050505050505050565b61100581565b600080611d9283613ae9565b9050611d9c6157dd565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a08401526101009091046001600160401b031660c0830152611e61576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c001516001600160401b031610611ec2576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611f0457600080fd5b505afa158015611f18573d6000803e3d6000fd5b505050506040513d6020811015611f2e57600080fd5b50519050808210801590611f4757506402540be4008206155b611f825760405162461bcd60e51b81526004018080602001828103825260378152602001806159e46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055611fdc615819565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f1935050505015801561201f573d6000803e3d6000fd5b5061200063f7a251d7600161203384613f4a565b612048876402540be40063ffffffff613aa716565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156120a657818101518382015260200161208e565b50505050905090810190601f1680156120d35780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156120f457600080fd5b505af1158015612108573d6000803e3d6000fd5b5050505083604001516001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600160405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561218a578181015183820152602001612172565b50505050905090810190601f1680156121b75780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25060019695505050505050565b61100881565b6001600160a01b03821660009081526002602052604081205460ff16156122305760405162461bcd60e51b815260040180806020018281038252602b815260200180615bbe602b913960400191505060405180910390fd5b600061223b83613ae9565b90506122456157dd565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a08401526101009091046001600160401b031660c083015261230a576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b03161461235e5760405162461bcd60e51b8152600401808060200182810382526045815260200180615a666045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156123a157600080fd5b505afa1580156123b5573d6000803e3d6000fd5b505050506040513d60208110156123cb57600080fd5b50516001600160a01b031614612428576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703230206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561246a57600080fd5b505afa15801561247e573d6000803e3d6000fd5b505050506040513d602081101561249457600080fd5b505190508082108015906124ad57506402540be4008206155b6124e85760405162461bcd60e51b81526004018080602001828103825260378152602001806159e46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055612542615819565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f19350505050158015612585573d6000803e3d6000fd5b5061200063f7a251d7600161259984613f4a565b6125ae876402540be40063ffffffff613aa716565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561260c5781810151838201526020016125f4565b50505050905090810190601f1680156126395780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561265a57600080fd5b505af115801561266e573d6000803e3d6000fd5b50505050876001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600760405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b838110156126ec5781810151838201526020016126d4565b50505050905090810190601f1680156127195780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b60035481565b33612000146127805760405162461bcd60e51b815260040180806020018281038252602f815260200180615b8f602f913960400191505060405180910390fd5b60ff8316600414156127d0576127cb82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613fc092505050565b61288a565b60ff83166005141561281b576127cb82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061436a92505050565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b6040805163bd46646160e01b81526001600160a01b0384166004820152905160009182916110049163bd466461916024808301926020929190829003018186803b1580156128dc57600080fd5b505afa1580156128f0573d6000803e3d6000fd5b505050506040513d602081101561290657600080fd5b5051146129445760405162461bcd60e51b815260040180806020018281038252602681526020018061590b6026913960400191505060405180910390fd5b6001600160a01b03831660009081526002602052604090205460ff161561299c5760405162461bcd60e51b815260040180806020018281038252602b815260200180615bbe602b913960400191505060405180910390fd5b60006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156129d957600080fd5b505afa1580156129ed573d6000803e3d6000fd5b505050506040513d6020811015612a0357600080fd5b505190506402540be4003406158015612a2e5750600354612a2a908263ffffffff6138be16565b3410155b612a695760405162461bcd60e51b815260040180806020018281038252604d815260200180615931604d913960600191505060405180910390fd5b42607801836001600160401b031610158015612a935750426201518001836001600160401b031611155b612ace5760405162461bcd60e51b81526004018080602001828103825260388152602001806159ac6038913960400191505060405180910390fd5b6000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612b0957600080fd5b505afa158015612b1d573d6000803e3d6000fd5b505050506040513d6020811015612b3357600080fd5b5051604080516318160ddd60e01b815290519192506000916001600160a01b038816916318160ddd916004808301926020929190829003018186803b158015612b7b57600080fd5b505afa158015612b8f573d6000803e3d6000fd5b505050506040513d6020811015612ba557600080fd5b50519050677ce66c50e2840000612bbf8260ff8516613918565b1115612c12576040805162461bcd60e51b815260206004820152601f60248201527f626570323020746f74616c20737570706c7920697320746f6f206c6172676500604482015290519081900360640190fd5b6060866001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015612c4d57600080fd5b505afa158015612c61573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612c8a57600080fd5b8101908080516040519392919084600160201b821115612ca957600080fd5b908301906020820185811115612cbe57600080fd5b8251600160201b811182820188101715612cd757600080fd5b82525081516020918201929091019080838360005b83811015612d04578181015183820152602001612cec565b50505050905090810190601f168015612d315780820380516001836020036101000a031916815260200191505b50604052505050905060608190506001815110158015612d5357506020815111155b612d8e5760405162461bcd60e51b8152600401808060200182810382526025815260200180615af16025913960400191505060405180910390fd5b6060886001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015612dc957600080fd5b505afa158015612ddd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612e0657600080fd5b8101908080516040519392919084600160201b821115612e2557600080fd5b908301906020820185811115612e3a57600080fd5b8251600160201b811182820188101715612e5357600080fd5b82525081516020918201929091019080838360005b83811015612e80578181015183820152602001612e68565b50505050905090810190601f168015612ead5780820380516001836020036101000a031916815260200191505b5060405250508151919250829160031180159150612ecd57508051600810155b612f085760405162461bcd60e51b8152600401808060200182810382526026815260200180615acb6026913960400191505060405180910390fd5b60005b81518160ff16101561300457606160f81b828260ff1681518110612f2b57fe5b01602001516001600160f81b03191610801590612f695750606160f81b828260ff1681518110612f5757fe5b01602001516001600160f81b03191611155b80612fc15750604160f81b828260ff1681518110612f8357fe5b01602001516001600160f81b03191610801590612fc15750602d60f91b828260ff1681518110612faf57fe5b01602001516001600160f81b03191611155b612ffc5760405162461bcd60e51b815260040180806020018281038252602a815260200180615b16602a913960400191505060405180910390fd5b600101612f0b565b50600354611004906108fc9061302190349063ffffffff61395816565b6040518115909202916000818181858888f19350505050158015613049573d6000803e3d6000fd5b506001600160a01b038a166000908152600260209081526040909120805460ff191660011790558481015190830151613080615830565b604051806101000160405280336001600160a01b031681526020018e6001600160a01b031681526020018481526020018381526020018981526020018a60ff1681526020016402540be400600354816130d557fe5b0481526001600160401b038e16602090910152905061200063f7a251d760046130fd8461460b565b61311b6402540be40061127c6003543461395890919063ffffffff16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015613179578181015183820152602001613161565b50505050905090810190601f1680156131a65780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156131c757600080fd5b505af11580156131db573d6000803e3d6000fd5b5050505060019a505050505050505050505092915050565b600781565b600981565b677ce66c50e284000081565b61100781565b61100681565b60005460ff1681565b336110071461325e5760405162461bcd60e51b815260040180806020018281038252602e815260200180615b61602e913960400191505060405180910390fd5b602081146132b3576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f880181900481028201810190925286815293945060609392508691508590819084018382808284376000920191909152505050506020830151909150686d6972726f7246656560b81b8114156133925760208201516402540be40081061561338a5760405162461bcd60e51b8152600401808060200182810382526022815260200180615be96022913960400191505060405180910390fd5b600355613448565b6673796e6346656560c81b81141561340b5760208201516402540be400810615613403576040805162461bcd60e51b815260206004820181905260248201527f7468652073796e634665652073686f756c64206265204e202a2031302a2a3130604482015290519081900360640190fd5b600455613448565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b61100281565b33612000146135235760405162461bcd60e51b815260040180806020018281038252602f815260200180615b8f602f913960400191505060405180910390fd5b60ff83166004141561356e576127cb82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061477d92505050565b60ff83166005141561281b576127cb82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061485792505050565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b039093169391929181169061010090046001600160401b031687565b61100381565b60045481565b61100081565b61271081565b61100481565b60606136386157dd565b600061364384614915565b9150915080613699576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff1661374c576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff0019166101006001600160401b03909216919091021790556138a3565b815160ff16600114156138565760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156137a557600080fd5b505afa1580156137b9573d6000803e3d6000fd5b505050506040513d60208110156137cf57600080fd5b505190506001600160a01b038116156138505760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b15801561383757600080fd5b505af115801561384b573d6000803e3d6000fd5b505050505b506138a3565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b600082820183811015610e57576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600060088211156139415761393a836007198401600a0a63ffffffff613aa716565b9050611355565b610e57836008849003600a0a63ffffffff614a6616565b6000610e5783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614abf565b60408051600580825260c08201909252606091829190816020015b60608152602001906001900390816139b557505083519091506139e0906001600160a01b0316614b56565b816000815181106139ed57fe5b6020026020010181905250613a0e83602001516001600160a01b0316614b56565b81600181518110613a1b57fe5b6020026020010181905250613a338360400151614b79565b81600281518110613a4057fe5b6020026020010181905250613a588360600151614b79565b81600381518110613a6557fe5b6020026020010181905250613a8683608001516001600160401b0316614b79565b81600481518110613a9357fe5b6020026020010181905250610e5781614b8c565b6000610e5783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614c16565b6020015190565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613b2c57600080fd5b505afa158015613b40573d6000803e3d6000fd5b505050506040513d6020811015613b5657600080fd5b5051604080516395d89b4160e01b8152905160ff90921692506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b158015613ba257600080fd5b505afa158015613bb6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015613bdf57600080fd5b8101908080516040519392919084600160201b821115613bfe57600080fd5b908301906020820185811115613c1357600080fd5b8251600160201b811182820188101715613c2c57600080fd5b82525081516020918201929091019080838360005b83811015613c59578181015183820152602001613c41565b50505050905090810190601f168015613c865780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b158015613cd657600080fd5b505afa158015613cea573d6000803e3d6000fd5b505050506040513d6020811015613d0057600080fd5b505160808701516060880151919250600091613d219163ffffffff61395816565b9050428760c001516001600160401b03161015613d4657506001935061135592505050565b613d54838860200151614c7b565b613d6657506002935061135592505050565b80821115613d7c57506003935061135592505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613dbe57600080fd5b505afa158015613dd2573d6000803e3d6000fd5b505050506040513d6020811015613de857600080fd5b505114613dfd57506004935061135592505050565b8660a0015160ff168414613e1957506005935061135592505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b158015613e5e57600080fd5b505afa158015613e72573d6000803e3d6000fd5b505050506040513d6020811015613e8857600080fd5b50516001600160a01b0316141580613f2a57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015613efb57600080fd5b505afa158015613f0f573d6000803e3d6000fd5b505050506040513d6020811015613f2557600080fd5b505114155b15613f3d57506006935061135592505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b6060815260200190600190039081613f635750508351909150613f8b9063ffffffff16614b79565b81600081518110613f9857fe5b6020026020010181905250613fb3836020015160001c614b79565b81600181518110613a9357fe5b613fc8615874565b6000613fd383614d63565b9150915080614029576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564206d6972726f722073796e207061636b61676500604482015290519081900360640190fd5b6020808301516001600160a01b03166000908152600290915260409020805460ff1916905560a082015160ff1661416e5760808201516040516110049180156108fc02916000818181858888f1935050505015801561408c573d6000803e3d6000fd5b506110046001600160a01b0316638eff336c8360600151846020015185604001516040518463ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b031681526020018260ff1681526020019350505050600060405180830381600087803b15801561410657600080fd5b505af115801561411a573d6000803e3d6000fd5b5050505081602001516001600160a01b03167f41787d7db08fc5907641ee8343379f28215727eb123d4b462099afab4300b03683606001516040518082815260200191505060405180910390a25050614367565b60a082015160ff16600114156141d85781602001516001600160a01b0316600080516020615aab83398151915260405180806020018281038252600e8152602001806d1b5a5c9c9bdc881d1a5b595bdd5d60921b81525060200191505060405180910390a2614307565b60a082015160ff166002141561424a5781602001516001600160a01b0316600080516020615aab83398151915260405180806020018281038252601681526020018075191d5c1b1a58d85d1959081091540c881cde5b589bdb60521b81525060200191505060405180910390a2614307565b60a082015160ff16600314156142b15781602001516001600160a01b0316600080516020615aab83398151915260405180806020018281038252600b8152602001806a1c9958591e48189bdd5b9960aa1b81525060200191505060405180910390a2614307565b81602001516001600160a01b0316600080516020615aab83398151915260405180806020018281038252600e8152602001806d3ab735b737bbb7103932b0b9b7b760911b81525060200191505060405180910390a25b815160808301516040516001600160a01b039092169161271091906000818181858888f193505050503d806000811461435c576040519150601f19603f3d011682016040523d82523d6000602084013e614361565b606091505b50505050505b50565b6143726158a9565b600061437d83614e70565b91509150806143d3576040805162461bcd60e51b815260206004820152601d60248201527f756e7265636f676e697a65642073796e632061636b207061636b616765000000604482015290519081900360640190fd5b606082015160ff166144535760408083015190516110049180156108fc02916000818181858888f19350505050158015614411573d6000803e3d6000fd5b5081602001516001600160a01b03167fbb7d3a9a559080d8281b0e4fb39dacbe2fdcafd5ef765e9a6ed871c9167dc60f60405160405180910390a25050614367565b606082015160ff16600114156144cd5781602001516001600160a01b03167fda94fdf17c7d624ee6572edd003d700d572ca82af7e7f049aba27cf7e2ed994b60405180806020018281038252600c8152602001806b1cde5b98c81d1a5b595bdd5d60a21b81525060200191505060405180910390a26145b6565b606082015160ff166002141561454e5781602001516001600160a01b03167fda94fdf17c7d624ee6572edd003d700d572ca82af7e7f049aba27cf7e2ed994b604051808060200182810382526013815260200180723737ba103137bab73210313c9036b4b93937b960691b81525060200191505060405180910390a26145b6565b81602001516001600160a01b03167fda94fdf17c7d624ee6572edd003d700d572ca82af7e7f049aba27cf7e2ed994b60405180806020018281038252600e8152602001806d3ab735b737bbb7103932b0b9b7b760911b81525060200191505060405180910390a25b815160408084015190516001600160a01b039092169161271091906000818181858888f193505050503d806000811461435c576040519150601f19603f3d011682016040523d82523d6000602084013e614361565b6040805160088082526101208201909252606091829190816020015b60608152602001906001900390816146275750508351909150614652906001600160a01b0316614b56565b8160008151811061465f57fe5b602002602001018190525061468083602001516001600160a01b0316614b56565b8160018151811061468d57fe5b60200260200101819052506146a8836040015160001c614b79565b816002815181106146b557fe5b60200260200101819052506146d0836060015160001c614b79565b816003815181106146dd57fe5b60200260200101819052506146f58360800151614b79565b8160048151811061470257fe5b602002602001018190525061471d8360a0015160ff16614b79565b8160058151811061472a57fe5b60200260200101819052506147428360c00151614b79565b8160068151811061474f57fe5b60200260200101819052506147708360e001516001600160401b0316614b79565b81600781518110613a9357fe5b614785615830565b600061479083614f3f565b91509150806147e6576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564206d6972726f722073796e207061636b61676500604482015290519081900360640190fd5b6020808301516001600160a01b03908116600090815260029092526040808320805460ff19169055845160c086015191519216926127109290818181858888f193505050503d806000811461435c576040519150601f19603f3d011682016040523d82523d6000602084013e614361565b61485f6157af565b600061486a83615090565b91509150806148c0576040805162461bcd60e51b815260206004820152601d60248201527f756e7265636f676e697a65642073796e632073796e207061636b616765000000604482015290519081900360640190fd5b815160608301516040516001600160a01b039092169161271091906000818181858888f193505050503d806000811461435c576040519150601f19603f3d011682016040523d82523d6000602084013e614361565b61491d6157dd565b60006149276157dd565b61492f6158d0565b61494061493b86615181565b6151a6565b90506000805b61494f836151f0565b15614a5957806149745761496a61496584615211565b61525f565b60ff168452614a51565b80600114156149935761498961496584615211565b6020850152614a51565b80600214156149c0576149ad6149a884615211565b615314565b6001600160a01b03166040850152614a51565b80600314156149df576149d561496584615211565b6060850152614a51565b80600414156149fe576149f461496584615211565b6080850152614a51565b8060051415614a2057614a1361496584615211565b60ff1660a0850152614a51565b8060061415614a4c57614a3561496584615211565b6001600160401b031660c085015260019150614a51565b614a59565b600101614946565b5091935090915050915091565b600082614a7557506000611355565b82820282848281614a8257fe5b0414610e575760405162461bcd60e51b8152600401808060200182810382526021815260200180615b406021913960400191505060405180910390fd5b60008184841115614b4e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614b13578181015183820152602001614afb565b50505050905090810190601f168015614b405780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60408051600560a21b8318601482015260348101909152606090610e578161532e565b6060611355614b8783615384565b61532e565b6060815160001415614bad57506040805160008152602081019091526114d9565b606082600081518110614bbc57fe5b602002602001015190506000600190505b8351811015614bfd57614bf382858381518110614be657fe5b602002602001015161546a565b9150600101614bcd565b50610e57614c10825160c060ff166154e7565b8261546a565b60008183614c655760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614b13578181015183820152602001614afb565b506000838581614c7157fe5b0495945050505050565b8151600090839060081080614c91575080516003115b15614ca0576000915050611355565b60408051602080825281830190925260609160208201818036833701905050905083602082015280825181518110614cd457fe5b6020910101516001600160f81b031916602d60f81b14614cf957600092505050611355565b600160005b8351811015614d5957828181518110614d1357fe5b602001015160f81c60f81b6001600160f81b031916848281518110614d3457fe5b01602001516001600160f81b03191614614d515760009150614d59565b600101614cfe565b5095945050505050565b614d6b615874565b6000614d75615874565b614d7d6158d0565b614d8961493b86615181565b90506000805b614d98836151f0565b15614a595780614dbe57614dae6149a884615211565b6001600160a01b03168452614e68565b8060011415614de657614dd36149a884615211565b6001600160a01b03166020850152614e68565b8060021415614e0857614dfb61496584615211565b60ff166040850152614e68565b8060031415614e2757614e1d61496584615211565b6060850152614e68565b8060041415614e4657614e3c61496584615211565b6080850152614e68565b8060051415614a4c57614e5b61496584615211565b60ff1660a0850152600191505b600101614d8f565b614e786158a9565b6000614e826158a9565b614e8a6158d0565b614e9661493b86615181565b90506000805b614ea5836151f0565b15614a595780614ecb57614ebb6149a884615211565b6001600160a01b03168452614f37565b8060011415614ef357614ee06149a884615211565b6001600160a01b03166020850152614f37565b8060021415614f1557614f0861496584615211565b60ff166040850152614f37565b8060031415614a4c57614f2a61496584615211565b60ff166060850152600191505b600101614e9c565b614f47615830565b6000614f51615830565b614f596158d0565b614f6561493b86615181565b90506000805b614f74836151f0565b15614a595780614f9a57614f8a6149a884615211565b6001600160a01b03168452615088565b8060011415614fc257614faf6149a884615211565b6001600160a01b03166020850152615088565b8060021415614fe157614fd761496584615211565b6040850152615088565b806003141561500057614ff661496584615211565b6060850152615088565b806004141561501f5761501561496584615211565b6080850152615088565b80600514156150415761503461496584615211565b60ff1660a0850152615088565b80600614156150605761505661496584615211565b60c0850152615088565b8060071415614a4c5761507561496584615211565b6001600160401b031660e0850152600191505b600101614f6b565b6150986157af565b60006150a26157af565b6150aa6158d0565b6150b661493b86615181565b90506000805b6150c5836151f0565b15614a5957806150eb576150db6149a884615211565b6001600160a01b03168452615179565b8060011415615113576151006149a884615211565b6001600160a01b03166020850152615179565b80600214156151325761512861496584615211565b6040850152615179565b80600314156151515761514761496584615211565b6060850152615179565b8060041415614a4c5761516661496584615211565b6001600160401b03166080850152600191505b6001016150bc565b6151896158f0565b506040805180820190915281518152602082810190820152919050565b6151ae6158d0565b6151b7826155df565b6151c057600080fd5b60006151cf8360200151615619565b60208085015160408051808201909152868152920190820152915050919050565b60006151fa6158f0565b505080518051602091820151919092015191011190565b6152196158f0565b615222826151f0565b61522b57600080fd5b6020820151600061523b8261567c565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061527457508151602110155b61527d57600080fd5b600061528c8360200151615619565b905080836000015110156152e7576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b8251602080850151830180519284900392918310156138b557506020919091036101000a90049392505050565b805160009060151461532557600080fd5b6113558261525f565b6060815160011480156153605750607f60f81b8260008151811061534e57fe5b01602001516001600160f81b03191611155b1561536c5750806114d9565b61135561537e8351608060ff166154e7565b8361546a565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166153c8575060186153ec565b6fffffffffffffffffffffffffffffffff1984166153e8575060106153ec565b5060005b60208110156154225781818151811061540157fe5b01602001516001600160f81b0319161561541a57615422565b6001016153ec565b60008160200390506060816040519080825280601f01601f191660200182016040528015615457576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561549b578051835260209283019201615483565b50855184518101855292509050808201602086015b818310156154c85780518352602092830192016154b0565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615537576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116155915782840160f81b8160008151811061557357fe5b60200101906001600160f81b031916908160001a9053509050611355565b606061559c85615384565b90508381510160370160f81b826000815181106155b557fe5b60200101906001600160f81b031916908160001a9053506155d6828261546a565b95945050505050565b80516000906155f0575060006114d9565b6020820151805160001a9060c082101561560f576000925050506114d9565b5060019392505050565b8051600090811a60808110156156335760009150506114d9565b60b881108061564e575060c0811080159061564e575060f881105b1561565d5760019150506114d9565b60c08110156156715760b5190190506114d9565b60f5190190506114d9565b80516000908190811a608081101561569757600191506157a8565b60b88110156156ac57607e19810191506157a8565b60c081101561572657600060b78203600186019550806020036101000a865104915060018101820193505080831015615720576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b506157a8565b60f881101561573b5760be19810191506157a8565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156157a6576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b60405180604001604052806158e36158f0565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe74686520626570323020746f6b656e2068617320616c7265616479206265656e20626f756e646d73672e76616c7565206d757374206265204e202a203165313020616e642067726561746572207468616e2073756d206f66206d696e6952656c617946656520616e64206d6972726f724665656f6e6c79206265703230206f776e65722063616e20617070726f766520746869732062696e64207265717565737465787069726554696d65206d7573742062652074776f206d696e75746573206c6174657220616e64206f6e6520646179206561726c69657272656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c61794665656d73672e76616c7565206d757374206265204e202a203165313020616e642067726561746572207468616e2073756d206f66206d696e6952656c617946656520616e642073796e63466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e642072657175657374686cd0e0baa629fe189a343f836065a7747c47dfc9fcb7e861f8b0f9e2b6b13962657032302073796d626f6c206c656e6774682073686f756c6420626520696e205b332c385d6265703230206e616d65206c656e6774682073686f756c6420626520696e205b312c33325d62657032302073796d626f6c206d757374206e6f7420636f6e7461696e206e6f6e2d616c706861626574536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e747261637474686520626570323020746f6b656e20697320696e206d6972726f722070656e64696e6720737461747573746865206d6972726f724665652073686f756c64206265204e202a2031302a2a3130a26469706673582212204405f2ae75dbf798048817e44c6572b86e9604267f0449e4a90c50f26dab3d5a64736f6c63430006040033" + "code": "0x6080604052600436106103975760003560e01c80637942fd05116101dc578063b795031711610102578063dc927faf116100a0578063fa9e91591161006f578063fa9e915914610d4e578063fc3e5908146105dd578063fd6a687914610d63578063fe3a2af51461056257610397565b8063dc927faf14610d0f578063e605bca014610d24578063e80561fa14610562578063f9a2bbc714610d3957610397565b8063c8509d81116100dc578063c8509d8114610c0a578063c8e704a4146105dd578063d117a11014610c8f578063d9e6dae91461072757610397565b8063b795031714610766578063bd32d3f9146104ef578063c81b166214610bf557610397565b806396713da91161017a578063a78abc1611610149578063a78abc1614610b00578063ab51bb9614610b15578063ab67a48514610766578063ac43175114610b2a57610397565b806396713da914610aac5780639a854bbd14610ac15780639dc0926214610ad6578063a1a11bf514610aeb57610397565b8063831d65d1116101b6578063831d65d1146109db578063859180fb1461071257806394553a4e14610a6257806395b9ad2614610a9757610397565b80637942fd05146109b15780637d078e13146105045780637ec816dd146109c657610397565b8063493279b1116102c1578063613684751161025f57806370fd5bad1161022e57806370fd5bad1461076657806372c4e0861461084457806375d47a0a146108e857806377d9dae8146108fd57610397565b8063613684751461072757806366dea52a146105dd5780636b3f13071461077b5780636e47b4821461082f57610397565b80634bf6c8821161029b5780634bf6c8821461072757806351e806721461073c5780635d499b1b146107515780635f558f861461076657610397565b8063493279b1146106e65780634a688818146105625780634bc81c001461071257610397565b80632d89ac3211610339578063401809f911610308578063401809f9146105dd57806343756e5c146105f2578063445fcefe14610623578063487c88ac1461050457610397565b80632d89ac32146105045780632e02d7761461057757806337e6ecda146105aa5780633dffc3871461050457610397565b80631f91600b116103755780631f91600b146104ef57806323996b531461050457806325c751b71461051957806328ae48621461056257610397565b80630bee7a671461039c5780630f212b1b146103ca5780631182b875146103f5575b600080fd5b3480156103a857600080fd5b506103b1610d78565b6040805163ffffffff9092168252519081900360200190f35b3480156103d657600080fd5b506103df610d7d565b6040805160ff9092168252519081900360200190f35b34801561040157600080fd5b5061047a6004803603604081101561041857600080fd5b60ff8235169190810190604081016020820135600160201b81111561043c57600080fd5b82018360208201111561044e57600080fd5b803590602001918460018302840111600160201b8311171561046f57600080fd5b509092509050610d82565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104b457818101518382015260200161049c565b50505050905090810190601f1680156104e15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104fb57600080fd5b506103df610e9c565b34801561051057600080fd5b506103df610ea1565b61054e6004803603604081101561052f57600080fd5b5080356001600160a01b031690602001356001600160401b0316610ea6565b604080519115158252519081900360200190f35b34801561056e57600080fd5b506103df6113f0565b34801561058357600080fd5b5061054e6004803603602081101561059a57600080fd5b50356001600160a01b03166113f5565b3480156105b657600080fd5b5061054e600480360360208110156105cd57600080fd5b50356001600160a01b031661140a565b3480156105e957600080fd5b506103df61141f565b3480156105fe57600080fd5b50610607611424565b604080516001600160a01b039092168252519081900360200190f35b34801561062f57600080fd5b506106d46004803603602081101561064657600080fd5b810190602081018135600160201b81111561066057600080fd5b82018360208201111561067257600080fd5b803590602001918460018302840111600160201b8311171561069357600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061142a945050505050565b60408051918252519081900360200190f35b3480156106f257600080fd5b506106fb611588565b6040805161ffff9092168252519081900360200190f35b34801561071e57600080fd5b506103df61158d565b34801561073357600080fd5b506103df611592565b34801561074857600080fd5b50610607611597565b34801561075d57600080fd5b506106d461159d565b34801561077257600080fd5b506103df6115a6565b61054e6004803603604081101561079157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156107bb57600080fd5b8201836020820111156107cd57600080fd5b803590602001918460018302840111600160201b831117156107ee57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506115ab945050505050565b34801561083b57600080fd5b50610607611e81565b61054e6004803603602081101561085a57600080fd5b810190602081018135600160201b81111561087457600080fd5b82018360208201111561088657600080fd5b803590602001918460018302840111600160201b831117156108a757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611e87945050505050565b3480156108f457600080fd5b506106076122d3565b61054e6004803603604081101561091357600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561093d57600080fd5b82018360208201111561094f57600080fd5b803590602001918460018302840111600160201b8311171561097057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506122d9945050505050565b3480156109bd57600080fd5b506103df6127df565b3480156109d257600080fd5b506106d46127e4565b3480156109e757600080fd5b50610a60600480360360408110156109fe57600080fd5b60ff8235169190810190604081016020820135600160201b811115610a2257600080fd5b820183602082011115610a3457600080fd5b803590602001918460018302840111600160201b83111715610a5557600080fd5b5090925090506127ea565b005b61054e60048036036040811015610a7857600080fd5b5080356001600160a01b031690602001356001600160401b0316612939565b348015610aa357600080fd5b506103df61329d565b348015610ab857600080fd5b506103df6132a2565b348015610acd57600080fd5b506106d46132a7565b348015610ae257600080fd5b506106076132b3565b348015610af757600080fd5b506106076132b9565b348015610b0c57600080fd5b5061054e6132bf565b348015610b2157600080fd5b506103b16113f0565b348015610b3657600080fd5b50610a6060048036036040811015610b4d57600080fd5b810190602081018135600160201b811115610b6757600080fd5b820183602082011115610b7957600080fd5b803590602001918460018302840111600160201b83111715610b9a57600080fd5b919390929091602081019035600160201b811115610bb757600080fd5b820183602082011115610bc957600080fd5b803590602001918460018302840111600160201b83111715610bea57600080fd5b5090925090506132c8565b348015610c0157600080fd5b50610607613587565b348015610c1657600080fd5b50610a6060048036036040811015610c2d57600080fd5b60ff8235169190810190604081016020820135600160201b811115610c5157600080fd5b820183602082011115610c6357600080fd5b803590602001918460018302840111600160201b83111715610c8457600080fd5b50909250905061358d565b348015610c9b57600080fd5b50610cb960048036036020811015610cb257600080fd5b5035613663565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a08301526001600160401b0390921660c082015290519081900360e00190f35b348015610d1b57600080fd5b506106076136ba565b348015610d3057600080fd5b506106d46136c0565b348015610d4557600080fd5b506106076136c6565b348015610d5a57600080fd5b506106d46136cc565b348015610d6f57600080fd5b506106076136d2565b606481565b600681565b60603361200014610dc45760405162461bcd60e51b815260040180806020018281038252602f815260200180615c89602f913960400191505060405180910390fd5b60ff841660011415610e1657610e0f83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506136d892505050565b9050610e95565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605848484604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1506040805160008152602081019091525b9392505050565b600481565b600181565b6040805163bd46646160e01b81526001600160a01b0384166004820152905160009182916110049163bd466461916024808301926020929190829003018186803b158015610ef357600080fd5b505afa158015610f07573d6000803e3d6000fd5b505050506040513d6020811015610f1d57600080fd5b50511415610f72576040805162461bcd60e51b815260206004820152601c60248201527f74686520626570323020746f6b656e206973206e6f7420626f756e6400000000604482015290519081900360640190fd5b6001600160a01b03831660009081526003602052604090205460ff16610fc95760405162461bcd60e51b8152600401808060200182810382526026815260200180615c636026913960400191505060405180910390fd5b60006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561100657600080fd5b505afa15801561101a573d6000803e3d6000fd5b505050506040513d602081101561103057600080fd5b505190506402540be400340615801561105b5750600554611057908263ffffffff61396816565b3410155b6110965760405162461bcd60e51b815260040180806020018281038252604b815260200180615aef604b913960600191505060405180910390fd5b42607801836001600160401b0316101580156110c05750426201518001836001600160401b031611155b6110fb5760405162461bcd60e51b8152600401808060200182810382526038815260200180615a806038913960400191505060405180910390fd5b6000846001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561113657600080fd5b505afa15801561114a573d6000803e3d6000fd5b505050506040513d602081101561116057600080fd5b50516040805163313ce56760e01b815290519192506000916001600160a01b0388169163313ce567916004808301926020929190829003018186803b1580156111a857600080fd5b505afa1580156111bc573d6000803e3d6000fd5b505050506040513d60208110156111d257600080fd5b50519050677ce66c50e28400006111ec8360ff84166139c2565b111561123f576040805162461bcd60e51b815260206004820152601f60248201527f626570323020746f74616c20737570706c7920697320746f6f206c6172676500604482015290519081900360640190fd5b600554611004906108fc9061125b90349063ffffffff613a0216565b6040518115909202916000818181858888f19350505050158015611283573d6000803e3d6000fd5b5061128c615883565b6040518060a00160405280336001600160a01b03168152602001886001600160a01b031681526020018481526020016402540be400600554816112cb57fe5b0481526001600160401b038816602090910152905061200063f7a251d760056112f384613a44565b61131d6402540be40061131160055434613a0290919063ffffffff16565b9063ffffffff613b5116565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561137b578181015183820152602001611363565b50505050905090810190601f1680156113a85780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b5050505060019450505050505b92915050565b600081565b60036020526000908152604090205460ff1681565b60026020526000908152604090205460ff1681565b600381565b61100181565b602081015160009061143a6158b1565b50600081815260016020818152604092839020835160e081018552815460ff9081168252938201549281019290925260028101546001600160a01b031693820184905260038101546060830152600481015460808301526005015491821660a08201526101009091046001600160401b031660c0820152906114c157600092505050611583565b600081604001516001600160a01b03166370a082316110046040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561151f57600080fd5b505afa158015611533573d6000803e3d6000fd5b505050506040513d602081101561154957600080fd5b50516080830151606084015191925060009161156a9163ffffffff613a0216565b905061157c818363ffffffff613a0216565b9450505050505b919050565b606081565b600581565b600881565b61200081565b6402540be40081565b600281565b6001600160a01b03821660009081526002602052604081205460ff16156116035760405162461bcd60e51b815260040180806020018281038252602b815260200180615cb8602b913960400191505060405180910390fd5b600061160e83613b93565b90506116186158b1565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a08401526101009091046001600160401b031660c08301526116dd576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b60006116fa82608001518360600151613a0290919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b0316146117505760405162461bcd60e51b8152600401808060200182810382526045815260200180615b3a6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b15801561179357600080fd5b505afa1580156117a7573d6000803e3d6000fd5b505050506040513d60208110156117bd57600080fd5b50516001600160a01b0316146118045760405162461bcd60e51b815260040180806020018281038252602e815260200180615a52602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b15801561185057600080fd5b505afa158015611864573d6000803e3d6000fd5b505050506040513d602081101561187a57600080fd5b505160408051636eb1769f60e11b81523360048201523060248201529051919250839161190b9184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b1580156118d357600080fd5b505afa1580156118e7573d6000803e3d6000fd5b505050506040513d60208110156118fd57600080fd5b50519063ffffffff61396816565b101561195e576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156119a057600080fd5b505afa1580156119b4573d6000803e3d6000fd5b505050506040513d60208110156119ca57600080fd5b505190508082108015906119e357506402540be4008206155b611a1e5760405162461bcd60e51b8152600401808060200182810382526037815260200180615ab86037913960400191505060405180910390fd5b6000611a2a868b613b9a565b905063ffffffff8116611c29576001600160a01b038a166323b872dd33611004611a5a898963ffffffff613a0216565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b158015611ac257600080fd5b505af1158015611ad6573d6000803e3d6000fd5b505050506040513d6020811015611aec57600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b158015611b5557600080fd5b505af1158015611b69573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015611be8578181015183820152602001611bd0565b50505050905090810190601f168015611c155780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2611ce1565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611ca5578181015183820152602001611c8d565b50505050905090810190601f168015611cd25780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055611d3b6158ed565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f19350505050158015611d83573d6000803e3d6000fd5b5061200063f7a251d76001611d9784613ff4565b611dac886402540be40063ffffffff613b5116565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611e0a578181015183820152602001611df2565b50505050905090810190601f168015611e375780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611e5857600080fd5b505af1158015611e6c573d6000803e3d6000fd5b5060019e9d5050505050505050505050505050565b61100581565b600080611e9383613b93565b9050611e9d6158b1565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a08401526101009091046001600160401b031660c0830152611f62576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c001516001600160401b031610611fc3576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561200557600080fd5b505afa158015612019573d6000803e3d6000fd5b505050506040513d602081101561202f57600080fd5b5051905080821080159061204857506402540be4008206155b6120835760405162461bcd60e51b8152600401808060200182810382526037815260200180615ab86037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556120dd6158ed565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f19350505050158015612120573d6000803e3d6000fd5b5061200063f7a251d7600161213484613ff4565b612149876402540be40063ffffffff613b5116565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156121a757818101518382015260200161218f565b50505050905090810190601f1680156121d45780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156121f557600080fd5b505af1158015612209573d6000803e3d6000fd5b5050505083604001516001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600160405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561228b578181015183820152602001612273565b50505050905090810190601f1680156122b85780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25060019695505050505050565b61100881565b6000806122e583613b93565b90506122ef6158b1565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a08401526101009091046001600160401b031660c08301526123b4576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146124085760405162461bcd60e51b8152600401808060200182810382526045815260200180615b3a6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b15801561244b57600080fd5b505afa15801561245f573d6000803e3d6000fd5b505050506040513d602081101561247557600080fd5b50516001600160a01b0316146124d2576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703230206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561251457600080fd5b505afa158015612528573d6000803e3d6000fd5b505050506040513d602081101561253e57600080fd5b5051905080821080159061255757506402540be4008206155b6125925760405162461bcd60e51b8152600401808060200182810382526037815260200180615ab86037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556125ec6158ed565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f1935050505015801561262f573d6000803e3d6000fd5b5061200063f7a251d7600161264384613ff4565b612658876402540be40063ffffffff613b5116565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156126b657818101518382015260200161269e565b50505050905090810190601f1680156126e35780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561270457600080fd5b505af1158015612718573d6000803e3d6000fd5b50505050876001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600760405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561279657818101518382015260200161277e565b50505050905090810190601f1680156127c35780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b60045481565b336120001461282a5760405162461bcd60e51b815260040180806020018281038252602f815260200180615c89602f913960400191505060405180910390fd5b60ff83166004141561287a5761287582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061406a92505050565b612934565b60ff8316600514156128c55761287582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061443092505050565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b6040805163bd46646160e01b81526001600160a01b0384166004820152905160009182916110049163bd466461916024808301926020929190829003018186803b15801561298657600080fd5b505afa15801561299a573d6000803e3d6000fd5b505050506040513d60208110156129b057600080fd5b5051146129ee5760405162461bcd60e51b81526004018080602001828103825260268152602001806159df6026913960400191505060405180910390fd5b6001600160a01b03831660009081526002602052604090205460ff1615612a465760405162461bcd60e51b815260040180806020018281038252602b815260200180615cb8602b913960400191505060405180910390fd5b60006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015612a8357600080fd5b505afa158015612a97573d6000803e3d6000fd5b505050506040513d6020811015612aad57600080fd5b505190506402540be4003406158015612ad85750600454612ad4908263ffffffff61396816565b3410155b612b135760405162461bcd60e51b815260040180806020018281038252604d815260200180615a05604d913960600191505060405180910390fd5b42607801836001600160401b031610158015612b3d5750426201518001836001600160401b031611155b612b785760405162461bcd60e51b8152600401808060200182810382526038815260200180615a806038913960400191505060405180910390fd5b6000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612bb357600080fd5b505afa158015612bc7573d6000803e3d6000fd5b505050506040513d6020811015612bdd57600080fd5b5051604080516318160ddd60e01b815290519192506000916001600160a01b038816916318160ddd916004808301926020929190829003018186803b158015612c2557600080fd5b505afa158015612c39573d6000803e3d6000fd5b505050506040513d6020811015612c4f57600080fd5b50519050677ce66c50e2840000612c698260ff85166139c2565b1115612cbc576040805162461bcd60e51b815260206004820152601f60248201527f626570323020746f74616c20737570706c7920697320746f6f206c6172676500604482015290519081900360640190fd5b6060866001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b158015612cf757600080fd5b505afa158015612d0b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612d3457600080fd5b8101908080516040519392919084600160201b821115612d5357600080fd5b908301906020820185811115612d6857600080fd5b8251600160201b811182820188101715612d8157600080fd5b82525081516020918201929091019080838360005b83811015612dae578181015183820152602001612d96565b50505050905090810190601f168015612ddb5780820380516001836020036101000a031916815260200191505b50604052505050905060608190506001815110158015612dfd57506020815111155b612e385760405162461bcd60e51b8152600401808060200182810382526025815260200180615bc56025913960400191505060405180910390fd5b6060886001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015612e7357600080fd5b505afa158015612e87573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612eb057600080fd5b8101908080516040519392919084600160201b821115612ecf57600080fd5b908301906020820185811115612ee457600080fd5b8251600160201b811182820188101715612efd57600080fd5b82525081516020918201929091019080838360005b83811015612f2a578181015183820152602001612f12565b50505050905090810190601f168015612f575780820380516001836020036101000a031916815260200191505b5060405250508151919250829160031180159150612f7757508051600810155b612fb25760405162461bcd60e51b8152600401808060200182810382526026815260200180615b9f6026913960400191505060405180910390fd5b60005b81518160ff1610156130ae57606160f81b828260ff1681518110612fd557fe5b01602001516001600160f81b031916108015906130135750606160f81b828260ff168151811061300157fe5b01602001516001600160f81b03191611155b8061306b5750604160f81b828260ff168151811061302d57fe5b01602001516001600160f81b0319161080159061306b5750602d60f91b828260ff168151811061305957fe5b01602001516001600160f81b03191611155b6130a65760405162461bcd60e51b815260040180806020018281038252602a815260200180615bea602a913960400191505060405180910390fd5b600101612fb5565b50600454611004906108fc906130cb90349063ffffffff613a0216565b6040518115909202916000818181858888f193505050501580156130f3573d6000803e3d6000fd5b506001600160a01b038a166000908152600260209081526040909120805460ff19166001179055848101519083015161312a615904565b604051806101000160405280336001600160a01b031681526020018e6001600160a01b031681526020018481526020018381526020018981526020018a60ff1681526020016402540be4006004548161317f57fe5b0481526001600160401b038e16602090910152905061200063f7a251d760046131a7846146d1565b6131c56402540be40061131160045434613a0290919063ffffffff16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561322357818101518382015260200161320b565b50505050905090810190601f1680156132505780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561327157600080fd5b505af1158015613285573d6000803e3d6000fd5b5050505060019a505050505050505050505092915050565b600781565b600981565b677ce66c50e284000081565b61100781565b61100681565b60005460ff1681565b33611007146133085760405162461bcd60e51b815260040180806020018281038252602e815260200180615c35602e913960400191505060405180910390fd5b6020811461335d576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f880181900481028201810190925286815293945060609392508691508590819084018382808284376000920191909152505050506020830151909150686d6972726f7246656560b81b81141561343c5760208201516402540be4008106156134345760405162461bcd60e51b8152600401808060200182810382526022815260200180615ce36022913960400191505060405180910390fd5b6004556134f2565b6673796e6346656560c81b8114156134b55760208201516402540be4008106156134ad576040805162461bcd60e51b815260206004820181905260248201527f7468652073796e634665652073686f756c64206265204e202a2031302a2a3130604482015290519081900360640190fd5b6005556134f2565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b61100281565b33612000146135cd5760405162461bcd60e51b815260040180806020018281038252602f815260200180615c89602f913960400191505060405180910390fd5b60ff8316600414156136185761287582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061484392505050565b60ff8316600514156128c55761287582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061492792505050565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b039093169391929181169061010090046001600160401b031687565b61100381565b60055481565b61100081565b61271081565b61100481565b60606136e26158b1565b60006136ed846149ec565b9150915080613743576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff166137f6576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff0019166101006001600160401b039092169190910217905561394d565b815160ff16600114156139005760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561384f57600080fd5b505afa158015613863573d6000803e3d6000fd5b505050506040513d602081101561387957600080fd5b505190506001600160a01b038116156138fa5760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b1580156138e157600080fd5b505af11580156138f5573d6000803e3d6000fd5b505050505b5061394d565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b600082820183811015610e95576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600060088211156139eb576139e4836007198401600a0a63ffffffff613b5116565b90506113ea565b610e95836008849003600a0a63ffffffff614b3d16565b6000610e9583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614b96565b60408051600580825260c08201909252606091829190816020015b6060815260200190600190039081613a5f5750508351909150613a8a906001600160a01b0316614c2d565b81600081518110613a9757fe5b6020026020010181905250613ab883602001516001600160a01b0316614c2d565b81600181518110613ac557fe5b6020026020010181905250613add8360400151614c50565b81600281518110613aea57fe5b6020026020010181905250613b028360600151614c50565b81600381518110613b0f57fe5b6020026020010181905250613b3083608001516001600160401b0316614c50565b81600481518110613b3d57fe5b6020026020010181905250610e9581614c63565b6000610e9583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614ced565b6020015190565b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613bd657600080fd5b505afa158015613bea573d6000803e3d6000fd5b505050506040513d6020811015613c0057600080fd5b5051604080516395d89b4160e01b8152905160ff90921692506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b158015613c4c57600080fd5b505afa158015613c60573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015613c8957600080fd5b8101908080516040519392919084600160201b821115613ca857600080fd5b908301906020820185811115613cbd57600080fd5b8251600160201b811182820188101715613cd657600080fd5b82525081516020918201929091019080838360005b83811015613d03578181015183820152602001613ceb565b50505050905090810190601f168015613d305780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b158015613d8057600080fd5b505afa158015613d94573d6000803e3d6000fd5b505050506040513d6020811015613daa57600080fd5b505160808701516060880151919250600091613dcb9163ffffffff613a0216565b9050428760c001516001600160401b03161015613df05750600193506113ea92505050565b613dfe838860200151614d52565b613e105750600293506113ea92505050565b80821115613e265750600393506113ea92505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e6857600080fd5b505afa158015613e7c573d6000803e3d6000fd5b505050506040513d6020811015613e9257600080fd5b505114613ea75750600493506113ea92505050565b8660a0015160ff168414613ec35750600593506113ea92505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b158015613f0857600080fd5b505afa158015613f1c573d6000803e3d6000fd5b505050506040513d6020811015613f3257600080fd5b50516001600160a01b0316141580613fd457506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015613fa557600080fd5b505afa158015613fb9573d6000803e3d6000fd5b505050506040513d6020811015613fcf57600080fd5b505114155b15613fe75750600693506113ea92505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b606081526020019060019003908161400d57505083519091506140359063ffffffff16614c50565b8160008151811061404257fe5b602002602001018190525061405d836020015160001c614c50565b81600181518110613b3d57fe5b614072615948565b600061407d83614e3a565b91509150806140d3576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564206d6972726f722073796e207061636b61676500604482015290519081900360640190fd5b6020808301516001600160a01b03166000908152600290915260409020805460ff1916905560a082015160ff166142345760808201516040516110049180156108fc02916000818181858888f19350505050158015614136573d6000803e3d6000fd5b506110046001600160a01b0316638eff336c8360600151846020015185604001516040518463ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b031681526020018260ff1681526020019350505050600060405180830381600087803b1580156141b057600080fd5b505af11580156141c4573d6000803e3d6000fd5b50505050602082810180516001600160a01b03908116600090815260038452604090819020805460ff1916600117905591516060860151835190815292519116927f41787d7db08fc5907641ee8343379f28215727eb123d4b462099afab4300b036928290030190a2505061442d565b60a082015160ff166001141561429e5781602001516001600160a01b0316600080516020615b7f83398151915260405180806020018281038252600e8152602001806d1b5a5c9c9bdc881d1a5b595bdd5d60921b81525060200191505060405180910390a26143cd565b60a082015160ff16600214156143105781602001516001600160a01b0316600080516020615b7f83398151915260405180806020018281038252601681526020018075191d5c1b1a58d85d1959081091540c881cde5b589bdb60521b81525060200191505060405180910390a26143cd565b60a082015160ff16600314156143775781602001516001600160a01b0316600080516020615b7f83398151915260405180806020018281038252600b8152602001806a1c9958591e48189bdd5b9960aa1b81525060200191505060405180910390a26143cd565b81602001516001600160a01b0316600080516020615b7f83398151915260405180806020018281038252600e8152602001806d3ab735b737bbb7103932b0b9b7b760911b81525060200191505060405180910390a25b815160808301516040516001600160a01b039092169161271091906000818181858888f193505050503d8060008114614422576040519150601f19603f3d011682016040523d82523d6000602084013e614427565b606091505b50505050505b50565b61443861597d565b600061444383614f47565b9150915080614499576040805162461bcd60e51b815260206004820152601d60248201527f756e7265636f676e697a65642073796e632061636b207061636b616765000000604482015290519081900360640190fd5b606082015160ff166145195760408083015190516110049180156108fc02916000818181858888f193505050501580156144d7573d6000803e3d6000fd5b5081602001516001600160a01b03167fbb7d3a9a559080d8281b0e4fb39dacbe2fdcafd5ef765e9a6ed871c9167dc60f60405160405180910390a2505061442d565b606082015160ff16600114156145935781602001516001600160a01b03167fda94fdf17c7d624ee6572edd003d700d572ca82af7e7f049aba27cf7e2ed994b60405180806020018281038252600c8152602001806b1cde5b98c81d1a5b595bdd5d60a21b81525060200191505060405180910390a261467c565b606082015160ff16600214156146145781602001516001600160a01b03167fda94fdf17c7d624ee6572edd003d700d572ca82af7e7f049aba27cf7e2ed994b604051808060200182810382526013815260200180723737ba103137bab73210313c9036b4b93937b960691b81525060200191505060405180910390a261467c565b81602001516001600160a01b03167fda94fdf17c7d624ee6572edd003d700d572ca82af7e7f049aba27cf7e2ed994b60405180806020018281038252600e8152602001806d3ab735b737bbb7103932b0b9b7b760911b81525060200191505060405180910390a25b815160408084015190516001600160a01b039092169161271091906000818181858888f193505050503d8060008114614422576040519150601f19603f3d011682016040523d82523d6000602084013e614427565b6040805160088082526101208201909252606091829190816020015b60608152602001906001900390816146ed5750508351909150614718906001600160a01b0316614c2d565b8160008151811061472557fe5b602002602001018190525061474683602001516001600160a01b0316614c2d565b8160018151811061475357fe5b602002602001018190525061476e836040015160001c614c50565b8160028151811061477b57fe5b6020026020010181905250614796836060015160001c614c50565b816003815181106147a357fe5b60200260200101819052506147bb8360800151614c50565b816004815181106147c857fe5b60200260200101819052506147e38360a0015160ff16614c50565b816005815181106147f057fe5b60200260200101819052506148088360c00151614c50565b8160068151811061481557fe5b60200260200101819052506148368360e001516001600160401b0316614c50565b81600781518110613b3d57fe5b61484b615904565b600061485683615013565b91509150806148ac576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564206d6972726f722073796e207061636b61676500604482015290519081900360640190fd5b6020828101516001600160a01b03908116600090815260029092526040808320805460ff19169055845160c08601519151921692612710926402540be4009092029190818181858888f193505050503d8060008114614422576040519150601f19603f3d011682016040523d82523d6000602084013e614427565b61492f615883565b600061493a83615164565b9150915080614990576040805162461bcd60e51b815260206004820152601d60248201527f756e7265636f676e697a65642073796e632073796e207061636b616765000000604482015290519081900360640190fd5b815160608301516040516001600160a01b0390921691612710916402540be40002906000818181858888f193505050503d8060008114614422576040519150601f19603f3d011682016040523d82523d6000602084013e614427565b6149f46158b1565b60006149fe6158b1565b614a066159a4565b614a17614a1286615255565b61527a565b90506000805b614a26836152c4565b15614b305780614a4b57614a41614a3c846152e5565b615333565b60ff168452614b28565b8060011415614a6a57614a60614a3c846152e5565b6020850152614b28565b8060021415614a9757614a84614a7f846152e5565b6153e8565b6001600160a01b03166040850152614b28565b8060031415614ab657614aac614a3c846152e5565b6060850152614b28565b8060041415614ad557614acb614a3c846152e5565b6080850152614b28565b8060051415614af757614aea614a3c846152e5565b60ff1660a0850152614b28565b8060061415614b2357614b0c614a3c846152e5565b6001600160401b031660c085015260019150614b28565b614b30565b600101614a1d565b5091935090915050915091565b600082614b4c575060006113ea565b82820282848281614b5957fe5b0414610e955760405162461bcd60e51b8152600401808060200182810382526021815260200180615c146021913960400191505060405180910390fd5b60008184841115614c255760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614bea578181015183820152602001614bd2565b50505050905090810190601f168015614c175780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60408051600560a21b8318601482015260348101909152606090610e9581615402565b60606113ea614c5e83615458565b615402565b6060815160001415614c845750604080516000815260208101909152611583565b606082600081518110614c9357fe5b602002602001015190506000600190505b8351811015614cd457614cca82858381518110614cbd57fe5b602002602001015161553e565b9150600101614ca4565b50610e95614ce7825160c060ff166155bb565b8261553e565b60008183614d3c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614bea578181015183820152602001614bd2565b506000838581614d4857fe5b0495945050505050565b8151600090839060081080614d68575080516003115b15614d775760009150506113ea565b60408051602080825281830190925260609160208201818036833701905050905083602082015280825181518110614dab57fe5b6020910101516001600160f81b031916602d60f81b14614dd0576000925050506113ea565b600160005b8351811015614e3057828181518110614dea57fe5b602001015160f81c60f81b6001600160f81b031916848281518110614e0b57fe5b01602001516001600160f81b03191614614e285760009150614e30565b600101614dd5565b5095945050505050565b614e42615948565b6000614e4c615948565b614e546159a4565b614e60614a1286615255565b90506000805b614e6f836152c4565b15614b305780614e9557614e85614a7f846152e5565b6001600160a01b03168452614f3f565b8060011415614ebd57614eaa614a7f846152e5565b6001600160a01b03166020850152614f3f565b8060021415614edf57614ed2614a3c846152e5565b60ff166040850152614f3f565b8060031415614efe57614ef4614a3c846152e5565b6060850152614f3f565b8060041415614f1d57614f13614a3c846152e5565b6080850152614f3f565b8060051415614b2357614f32614a3c846152e5565b60ff1660a0850152600191505b600101614e66565b614f4f61597d565b6000614f5961597d565b614f616159a4565b614f6d614a1286615255565b90506000805b614f7c836152c4565b15614b305780614fa257614f92614a7f846152e5565b6001600160a01b0316845261500b565b8060011415614fca57614fb7614a7f846152e5565b6001600160a01b0316602085015261500b565b8060021415614fe957614fdf614a3c846152e5565b604085015261500b565b8060031415614b2357614ffe614a3c846152e5565b60ff166060850152600191505b600101614f73565b61501b615904565b6000615025615904565b61502d6159a4565b615039614a1286615255565b90506000805b615048836152c4565b15614b30578061506e5761505e614a7f846152e5565b6001600160a01b0316845261515c565b806001141561509657615083614a7f846152e5565b6001600160a01b0316602085015261515c565b80600214156150b5576150ab614a3c846152e5565b604085015261515c565b80600314156150d4576150ca614a3c846152e5565b606085015261515c565b80600414156150f3576150e9614a3c846152e5565b608085015261515c565b806005141561511557615108614a3c846152e5565b60ff1660a085015261515c565b80600614156151345761512a614a3c846152e5565b60c085015261515c565b8060071415614b2357615149614a3c846152e5565b6001600160401b031660e0850152600191505b60010161503f565b61516c615883565b6000615176615883565b61517e6159a4565b61518a614a1286615255565b90506000805b615199836152c4565b15614b3057806151bf576151af614a7f846152e5565b6001600160a01b0316845261524d565b80600114156151e7576151d4614a7f846152e5565b6001600160a01b0316602085015261524d565b8060021415615206576151fc614a3c846152e5565b604085015261524d565b80600314156152255761521b614a3c846152e5565b606085015261524d565b8060041415614b235761523a614a3c846152e5565b6001600160401b03166080850152600191505b600101615190565b61525d6159c4565b506040805180820190915281518152602082810190820152919050565b6152826159a4565b61528b826156b3565b61529457600080fd5b60006152a383602001516156ed565b60208085015160408051808201909152868152920190820152915050919050565b60006152ce6159c4565b505080518051602091820151919092015191011190565b6152ed6159c4565b6152f6826152c4565b6152ff57600080fd5b6020820151600061530f82615750565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061534857508151602110155b61535157600080fd5b600061536083602001516156ed565b905080836000015110156153bb576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561395f57506020919091036101000a90049392505050565b80516000906015146153f957600080fd5b6113ea82615333565b6060815160011480156154345750607f60f81b8260008151811061542257fe5b01602001516001600160f81b03191611155b15615440575080611583565b6113ea6154528351608060ff166155bb565b8361553e565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff19841661549c575060186154c0565b6fffffffffffffffffffffffffffffffff1984166154bc575060106154c0565b5060005b60208110156154f6578181815181106154d557fe5b01602001516001600160f81b031916156154ee576154f6565b6001016154c0565b60008160200390506060816040519080825280601f01601f19166020018201604052801561552b576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561556f578051835260209283019201615557565b50855184518101855292509050808201602086015b8183101561559c578051835260209283019201615584565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061560b576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116156655782840160f81b8160008151811061564757fe5b60200101906001600160f81b031916908160001a90535090506113ea565b606061567085615458565b90508381510160370160f81b8260008151811061568957fe5b60200101906001600160f81b031916908160001a9053506156aa828261553e565b95945050505050565b80516000906156c457506000611583565b6020820151805160001a9060c08210156156e357600092505050611583565b5060019392505050565b8051600090811a6080811015615707576000915050611583565b60b8811080615722575060c08110801590615722575060f881105b15615731576001915050611583565b60c08110156157455760b519019050611583565b60f519019050611583565b80516000908190811a608081101561576b576001915061587c565b60b881101561578057607e198101915061587c565b60c08110156157fa57600060b78203600186019550806020036101000a8651049150600181018201935050808310156157f4576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061587c565b60f881101561580f5760be198101915061587c565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561587a576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b60405180604001604052806159b76159c4565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe74686520626570323020746f6b656e2068617320616c7265616479206265656e20626f756e646d73672e76616c7565206d757374206265204e202a203165313020616e642067726561746572207468616e2073756d206f66206d696e6952656c617946656520616e64206d6972726f724665656f6e6c79206265703230206f776e65722063616e20617070726f766520746869732062696e64207265717565737465787069726554696d65206d7573742062652074776f206d696e75746573206c6174657220616e64206f6e6520646179206561726c69657272656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c61794665656d73672e76616c7565206d757374206265204e202a203165313020616e642067726561746572207468616e2073756d206f66206d696e6952656c617946656520616e642073796e63466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e642072657175657374686cd0e0baa629fe189a343f836065a7747c47dfc9fcb7e861f8b0f9e2b6b13962657032302073796d626f6c206c656e6774682073686f756c6420626520696e205b332c385d6265703230206e616d65206c656e6774682073686f756c6420626520696e205b312c33325d62657032302073796d626f6c206d757374206e6f7420636f6e7461696e206e6f6e2d616c706861626574536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637474686520626570323020746f6b656e206973206e6f7420626f756e64206279206d6972726f72746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e747261637474686520626570323020746f6b656e20697320696e206d6972726f722070656e64696e6720737461747573746865206d6972726f724665652073686f756c64206265204e202a2031302a2a3130a264697066735822122014588f541c80c4edbdd246cf15b7144a7367427fd455df156246cb75e37bdfc464736f6c63430006040033" }, "0x0000000000000000000000000000000000002000": { "balance": "0x0", diff --git a/test/TestTokenHub.js b/test/TestTokenHub.js index d652f8e1..24da016c 100644 --- a/test/TestTokenHub.js +++ b/test/TestTokenHub.js @@ -72,6 +72,12 @@ function buildAckPackagePrefix() { )); } +function buildFailAckPackagePrefix() { + return Buffer.from(web3.utils.hexToBytes( + "0x02" + toBytes32String(0) + )); +} + function buildBindPackage(bindType, bep2TokenSymbol, bep20Addr, totalSupply, peggyAmount, decimals) { let timestamp = Math.floor(Date.now() / 1000); // counted by second let initialExpireTimeStr = (timestamp + 3).toString(16); // expire at 5 second later @@ -951,13 +957,21 @@ contract('TokenHub', (accounts) => { try { let timestamp = Math.floor(Date.now() / 1000); // counted by second let expireTime = timestamp + 300; // expire at five minutes later - const tx1 = await tokenManager.mirror(miniToken.address, expireTime, {from: player, value: miniRelayFee.add(mirrorFee)}); - console.log(tx1); + await tokenManager.mirror(miniToken.address, expireTime, {from: player, value: miniRelayFee.add(mirrorFee)}); assert.fail(); } catch (error) { assert.ok(error.toString().includes("the bep20 token has already been bound")); } + try { + let timestamp = Math.floor(Date.now() / 1000); // counted by second + let expireTime = timestamp + 100; // expire at five minutes later + await tokenManager.mirror(xyzToken.address, expireTime, {from: player, value: miniRelayFee.add(mirrorFee)}); + assert.fail(); + } catch (error) { + assert.ok(error.toString().includes("expireTime must be two minutes later and one day earlier")); + } + try { await xyzToken.setName("", {from: xyzTokenOwner}); @@ -1037,7 +1051,7 @@ contract('TokenHub', (accounts) => { let timestamp = Math.floor(Date.now() / 1000); // counted by second let expireTime = timestamp + 300; // expire at five minutes later - const tx1 = await tokenManager.mirror(xyzToken.address, expireTime, {from: player, value: miniRelayFee.add(mirrorFee)}); + await tokenManager.mirror(xyzToken.address, expireTime, {from: player, value: miniRelayFee.add(mirrorFee)}); assert.fail(); } catch (error) { assert.ok(error.toString().includes("bep20 total supply is too large")); @@ -1133,7 +1147,21 @@ contract('TokenHub', (accounts) => { let tokenManagerBalance = await web3.eth.getBalance(tokenManager.address); assert.equal(web3.utils.toBN(tokenManagerBalance).eq(mirrorFee), true, "wrong tokenManager balance"); - const mirrorChannelSeq = await crossChain.channelReceiveSequenceMap(MIRROR_CHANNELID); + // mirror fail ack + let mirrorChannelSeq = await crossChain.channelReceiveSequenceMap(MIRROR_CHANNELID); + const mirrorFailAckPackageBytes = Buffer.from(web3.utils.hexToBytes(nestedEventValues.payload)); + await crossChain.handlePackage(Buffer.concat([buildFailAckPackagePrefix(), mirrorFailAckPackageBytes.subarray(33, mirrorFailAckPackageBytes.length)]), proof, merkleHeight, mirrorChannelSeq, MIRROR_CHANNELID, {from: relayer}); + tokenManagerBalance = await web3.eth.getBalance(tokenManager.address); + assert.equal(web3.utils.toBN(tokenManagerBalance).eq(web3.utils.toBN(0)), true, "wrong tokenManager balance"); + + // success mirror + timestamp = Math.floor(Date.now() / 1000); // counted by second + expireTime = timestamp + 300; // expire at five minutes later + tx = await tokenManager.mirror(xyzToken.address, expireTime, {from: player, value: miniRelayFee.add(mirrorFee)}); + tokenManagerBalance = await web3.eth.getBalance(tokenManager.address); + assert.equal(web3.utils.toBN(tokenManagerBalance).eq(mirrorFee), true, "wrong tokenManager balance"); + + mirrorChannelSeq = await crossChain.channelReceiveSequenceMap(MIRROR_CHANNELID); const mirrorAckPackageBytes = buildMirrorAckPackage(player, xyzToken.address, 18, "XYZ-123", mirrorFee, 0); await crossChain.handlePackage(mirrorAckPackageBytes, proof, merkleHeight, mirrorChannelSeq, MIRROR_CHANNELID, {from: relayer}); @@ -1158,5 +1186,96 @@ contract('TokenHub', (accounts) => { assert.equal(web3.utils.toBN(decodedSyncSynPackage.syncFee).mul(web3.utils.toBN(1e10)).eq(syncFee), true, "Wrong mirrorFee in sync syn package"); tokenManagerBalance = await web3.eth.getBalance(tokenManager.address); assert.equal(web3.utils.toBN(tokenManagerBalance).eq(syncFee), true, "wrong tokenManager balance"); + + // sync fail ack package + let syncChannelSeq = await crossChain.channelReceiveSequenceMap(SYNC_CHANNELID); + const syncFailAckPackageBytes = Buffer.from(web3.utils.hexToBytes(nestedEventValues.payload)); + await crossChain.handlePackage(Buffer.concat([buildFailAckPackagePrefix(), syncFailAckPackageBytes.subarray(33, syncFailAckPackageBytes.length)]), proof, merkleHeight, syncChannelSeq, SYNC_CHANNELID, {from: relayer}); + tokenManagerBalance = await web3.eth.getBalance(tokenManager.address); + assert.equal(web3.utils.toBN(tokenManagerBalance).eq(web3.utils.toBN(0)), true, "wrong tokenManager balance"); + + // success sync and sync ack + timestamp = Math.floor(Date.now() / 1000); // counted by second + expireTime = timestamp + 300; // expire at five minutes later + await tokenManager.sync(xyzToken.address, expireTime, {from: player, value: miniRelayFee.add(syncFee)}); + tokenManagerBalance = await web3.eth.getBalance(tokenManager.address); + assert.equal(web3.utils.toBN(tokenManagerBalance).eq(syncFee), true, "wrong tokenManager balance"); + + syncChannelSeq = await crossChain.channelReceiveSequenceMap(SYNC_CHANNELID); + await crossChain.handlePackage(buildSyncAckPackage(player, xyzToken.address, syncFee, 0), proof, merkleHeight, syncChannelSeq, SYNC_CHANNELID, {from: relayer}); + tokenManagerBalance = await web3.eth.getBalance(tokenManager.address); + assert.equal(web3.utils.toBN(tokenManagerBalance).eq(web3.utils.toBN(0)), true, "wrong tokenManager balance"); + }); + it('iterate sync failures', async () => { + const tokenManager = await TokenManager.deployed(); + const tokenHub = await TokenHub.deployed(); + const miniToken = await MiniToken.deployed(); + const defToken = await DEFToken.deployed(); + const xyzToken = await XYZToken.deployed(); + const crossChain = await CrossChain.deployed(); + const miniRelayFee = await tokenHub.getMiniRelayFee(); + const mirrorFee = await tokenManager.mirrorFee(); + const xyzTokenOwner = accounts[0]; + const relayer = accounts[1]; + const player = accounts[2]; + + const syncFee = await tokenManager.syncFee(); + + try { + let timestamp = Math.floor(Date.now() / 1000); // counted by second + let expireTime = timestamp + 300; // expire at five minutes later + await tokenManager.sync(defToken.address, expireTime, { + from: player, + value: miniRelayFee.add(syncFee) + }); + assert.fail(); + } catch (error) { + assert.ok(error.toString().includes("the bep20 token is not bound")); + } + + try { + let timestamp = Math.floor(Date.now() / 1000); // counted by second + let expireTime = timestamp + 300; // expire at five minutes later + await tokenManager.sync(miniToken.address, expireTime, { + from: player, + value: miniRelayFee.add(syncFee) + }); + assert.fail(); + } catch (error) { + assert.ok(error.toString().includes("the bep20 token is not bound by mirror")); + } + + try { + let timestamp = Math.floor(Date.now() / 1000); // counted by second + let expireTime = timestamp + 100; // expire at five minutes later + await tokenManager.sync(xyzToken.address, expireTime, { + from: player, + value: miniRelayFee.add(syncFee) + }); + assert.fail(); + } catch (error) { + assert.ok(error.toString().includes("expireTime must be two minutes later and one day earlier")); + } + + try { + await xyzToken.setTotalSupply(web3.utils.toBN(1e18).mul(web3.utils.toBN(1e18)), {from: xyzTokenOwner}); + + let timestamp = Math.floor(Date.now() / 1000); // counted by second + let expireTime = timestamp + 300; // expire at five minutes later + await tokenManager.sync(xyzToken.address, expireTime, {from: player, value: miniRelayFee.add(mirrorFee)}); + assert.fail(); + } catch (error) { + assert.ok(error.toString().includes("bep20 total supply is too large")); + } + + await xyzToken.setTotalSupply(web3.utils.toBN(1e18).mul(web3.utils.toBN(1e8)), {from: xyzTokenOwner}); + const xyzTokenNewTotalSupply = await xyzToken.totalSupply(); + + timestamp = Math.floor(Date.now() / 1000); // counted by second + expireTime = timestamp + 300; // expire at five minutes later + tx = await tokenManager.sync(xyzToken.address, expireTime, {from: player, value: miniRelayFee.add(syncFee)}); + nestedEventValues = (await truffleAssert.createTransactionResult(crossChain, tx.tx)).logs[0].args; + let decodedSyncSynPackage = decodeSyncSynPackage(nestedEventValues.payload); + assert.equal(web3.utils.toBN(decodedSyncSynPackage.bep20Supply).eq(xyzTokenNewTotalSupply), true, "Wrong total supply in sync syn package"); }); });