Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- MultisigWallet
- Optimization enabled
- true
- Compiler version
- v0.8.17+commit.8df45f5f
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:33:28.204465Z
Constructor Arguments
0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000004cc3a18209517a09f472639551357db80a17412b000000000000000000000000cb9539df5a8617c4b39105f3d3a614ab72b94f5b000000000000000000000000c9bea9379a8fade01240ee583535fac713b7101400000000000000000000000012d61e143e780ce904ce16f764668511708b2e31000000000000000000000000600360f031a22213522329c41ead9f0a4d6f37ff000000000000000000000000af329a2986d7f78991ab5aedad6c7c3a2bc760a5
Contract source code
// SPDX-License-Identifier: No License (None) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256` * (`UintSet`) are supported. */ library EnumerableSet { struct AddressSet { // Storage of set values address[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (address => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { if (!contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. address lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Replace a current value from a set with the new value. * * Returns true if the value was replaced, and false if newValue already in set or currentValue is not in set */ function replace(AddressSet storage set, address currentValue, address newValue) internal returns (bool) { uint256 currentIndex = set._indexes[currentValue]; if (contains(set, newValue) || currentIndex == 0) { return false; } else { set._values[currentIndex - 1] = newValue; set._indexes[newValue] = currentIndex; delete set._indexes[currentValue]; return true; } } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns 1-based index of value in the set. O(1). */ function indexOf(AddressSet storage set, address value) internal view returns (uint256) { return set._indexes[value]; } /** * @dev Returns the number of values on the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } } contract MultisigWallet { using EnumerableSet for EnumerableSet.AddressSet; struct Ballot { uint128 votes; // bitmap of unique votes (max 127 votes) uint64 expire; // time when ballot expire uint8 yea; // number of votes `Yea` } EnumerableSet.AddressSet owners; // founders may transfer contract's ownership uint256 public ownersSetCounter; // each time when change owners increase the counter uint256 public expirePeriod = 3 days; mapping(bytes32 => Ballot) public ballots; uint256 public minRequired; // minimum voters required to approve. If 0 then required 50% + 1 vote. event SetOwner(address owner, bool isEnable); event CreateBallot(bytes32 ballotHash, uint256 expired); event Execute(bytes32 ballotHash, address to, uint256 value, bytes data); modifier onlyThis() { require(address(this) == msg.sender, "Only multisig allowed"); _; } // add list of owners and minimum voters required to approve (if 0 then required 50% + 1 vote). constructor (address[] memory _owners, uint256 _minRequired) { for (uint i = 0; i < _owners.length; i++) { require(_owners[i] != address(0), "Zero address"); owners.add(_owners[i]); } require(_minRequired <= owners.length(), "_minRequired too big"); minRequired = _minRequired; } // get number of owners function getOwnersNumber() external view returns(uint256) { return owners.length(); } // returns list of owners addresses function getOwners() external view returns(address[] memory) { return owners._values; } // add owner function addOwner(address owner) external onlyThis{ require(owner != address(0), "Zero address"); require(owners.length() < 127, "Too many owners"); require(owners.add(owner), "Owner already added"); ownersSetCounter++; // change owners set emit SetOwner(owner, true); } // remove owner function removeOwner(address owner) external onlyThis{ require(owners.length() > 1, "Remove all owners is not allowed"); require(owners.remove(owner), "Owner does not exist"); ownersSetCounter++; // change owners set emit SetOwner(owner, false); } // change owner address function changeOwnerAddress(address currentAddress, address newAddress) external onlyThis{ require(newAddress != address(0), "Zero address"); require(owners.replace(currentAddress, newAddress), "currentAddress does not exist or newAddress already exist"); emit SetOwner(currentAddress, false); emit SetOwner(newAddress, true); } // set minimum voters required to approve (if 0 then required 50% + 1 vote). function setMinRequired(uint256 _minRequired) external onlyThis{ require(_minRequired <= owners.length(), "_minRequired too big"); minRequired = _minRequired; } function setExpirePeriod(uint256 period) external onlyThis { require(period >= 1 days, "Too short period"); // avoid deadlock in case of set too short period expirePeriod = period; } function vote(address to, uint256 value, bytes calldata data) external { uint256 index = owners.indexOf(msg.sender); require(index != 0, "Only owner"); bytes32 ballotHash = keccak256(abi.encodePacked(to, value, data, ownersSetCounter)); Ballot memory b = ballots[ballotHash]; if (b.expire == 0 || b.expire < uint64(block.timestamp)) { // if no ballot or ballot expired - create new ballot b.expire = uint64(block.timestamp + expirePeriod); b.votes = 0; b.yea = 0; emit CreateBallot(ballotHash, b.expire); } uint256 mask = 1 << index; if (b.votes & mask == 0) { // this owner don't vote yet. b.votes = uint128(b.votes | mask); // record owner's vote b.yea += 1; // increase total votes "Yea" } if (isApproved(b.yea)) { delete ballots[ballotHash]; execute(to, value, data); emit Execute(ballotHash, to, value, data); } else { // update ballot ballots[ballotHash] = b; } } function isApproved(uint256 votesYea) internal view returns(bool) { // use local variables to save gas uint256 _minRequired = minRequired; uint256 _ownersLength = owners.length(); if (_minRequired == 0 || _minRequired > _ownersLength) { // to avoid deadlock minRequired can't be bigger than number of owners. return (votesYea >= _ownersLength / 2 + 1); // vote "Yea" > 50% of owners } else { return (votesYea >= _minRequired); // vote "Yea" >= minimum required } } function execute(address to, uint256 value, bytes memory data) internal { (bool success,) = to.call{value: value}(data); require(success, "Execute error"); } // allow receive ERC223 tokens function tokenReceived(address _from, uint _value, bytes calldata _data) external {} // allow receive ERC721 tokens (NFT) function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external pure returns(bytes4) { return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); } // allow receive coin receive() external payable {} }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address[]","name":"_owners","internalType":"address[]"},{"type":"uint256","name":"_minRequired","internalType":"uint256"}]},{"type":"event","name":"CreateBallot","inputs":[{"type":"bytes32","name":"ballotHash","internalType":"bytes32","indexed":false},{"type":"uint256","name":"expired","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Execute","inputs":[{"type":"bytes32","name":"ballotHash","internalType":"bytes32","indexed":false},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false},{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"SetOwner","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"bool","name":"isEnable","internalType":"bool","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"votes","internalType":"uint128"},{"type":"uint64","name":"expire","internalType":"uint64"},{"type":"uint8","name":"yea","internalType":"uint8"}],"name":"ballots","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeOwnerAddress","inputs":[{"type":"address","name":"currentAddress","internalType":"address"},{"type":"address","name":"newAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"expirePeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getOwners","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getOwnersNumber","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minRequired","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes4","name":"","internalType":"bytes4"}],"name":"onERC721Received","inputs":[{"type":"address","name":"_operator","internalType":"address"},{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"ownersSetCounter","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setExpirePeriod","inputs":[{"type":"uint256","name":"period","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinRequired","inputs":[{"type":"uint256","name":"_minRequired","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"tokenReceived","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"vote","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x60806040526203f4806003553480156200001857600080fd5b5060405162001558380380620015588339810160408190526200003b9162000228565b60005b8251811015620001085760006001600160a01b031683828151811062000068576200006862000302565b60200260200101516001600160a01b031603620000bb5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b60448201526064015b60405180910390fd5b620000f2838281518110620000d457620000d462000302565b602002602001015160006200017b60201b62000adb1790919060201c565b5080620000ff8162000318565b9150506200003e565b50620001206000620001f160201b62000b4f1760201c565b811115620001715760405162461bcd60e51b815260206004820152601460248201527f5f6d696e526571756972656420746f6f206269670000000000000000000000006044820152606401620000b2565b6005555062000340565b6001600160a01b0381166000908152600183016020526040812054620001e757508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b03861690811790915585549082528286019093526040902091909155620001eb565b5060005b92915050565b5490565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200022357600080fd5b919050565b600080604083850312156200023c57600080fd5b82516001600160401b03808211156200025457600080fd5b818501915085601f8301126200026957600080fd5b8151602082821115620002805762000280620001f5565b8160051b604051601f19603f83011681018181108682111715620002a857620002a8620001f5565b604052928352818301935084810182019289841115620002c757600080fd5b948201945b83861015620002f057620002e0866200020b565b85529482019493820193620002cc565b97909101519698969750505050505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016200033957634e487b7160e01b600052601160045260246000fd5b5060010190565b61120880620003506000396000f3fe6080604052600436106100e15760003560e01c80637dd0dd161161007f5780638943ec02116100595780638943ec02146102bc578063a0e67e2b146102dd578063c1d74a4c146102ff578063d7a52fa91461031f57600080fd5b80637dd0dd16146102025780638638fb5a1461028757806386cbaed81461029c57600080fd5b8063173825d9116100bb578063173825d91461018a57806321407e53146101ac5780632203d796146101c25780637065cb48146101e257600080fd5b806313e26d58146100ed578063150b7a0214610116578063163d262f1461017457600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010360055481565b6040519081526020015b60405180910390f35b34801561012257600080fd5b5061015b610131366004610e98565b7f150b7a023d4804d13e8c85fb27262cb750cf6ba9f9dd3bb30d90f482ceeb4b1f95945050505050565b6040516001600160e01b0319909116815260200161010d565b34801561018057600080fd5b5061010360025481565b34801561019657600080fd5b506101aa6101a5366004610f07565b61033f565b005b3480156101b857600080fd5b5061010360035481565b3480156101ce57600080fd5b506101aa6101dd366004610f22565b610456565b3480156101ee57600080fd5b506101aa6101fd366004610f07565b6104c3565b34801561020e57600080fd5b5061025661021d366004610f22565b6004602052600090815260409020546001600160801b03811690600160801b810467ffffffffffffffff1690600160c01b900460ff1683565b604080516001600160801b03909416845267ffffffffffffffff909216602084015260ff169082015260600161010d565b34801561029357600080fd5b50600054610103565b3480156102a857600080fd5b506101aa6102b7366004610f3b565b610600565b3480156102c857600080fd5b506101aa6102d7366004610f3b565b50505050565b3480156102e957600080fd5b506102f26108c7565b60405161010d9190610f95565b34801561030b57600080fd5b506101aa61031a366004610fe2565b61092b565b34801561032b57600080fd5b506101aa61033a366004610f22565b610a71565b3033146103675760405162461bcd60e51b815260040161035e90611015565b60405180910390fd5b600161037260005490565b116103bf5760405162461bcd60e51b815260206004820181905260248201527f52656d6f766520616c6c206f776e657273206973206e6f7420616c6c6f776564604482015260640161035e565b6103ca600082610b53565b61040d5760405162461bcd60e51b815260206004820152601460248201527313dddb995c88191bd95cc81b9bdd08195e1a5cdd60621b604482015260640161035e565b6002805490600061041d8361105a565b9091555050604080516001600160a01b0383168152600060208201526000805160206111b383398151915291015b60405180910390a150565b3033146104755760405162461bcd60e51b815260040161035e90611015565b6000548111156104be5760405162461bcd60e51b81526020600482015260146024820152735f6d696e526571756972656420746f6f2062696760601b604482015260640161035e565b600555565b3033146104e25760405162461bcd60e51b815260040161035e90611015565b6001600160a01b0381166105275760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640161035e565b607f61053260005490565b106105715760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206f776e65727360881b604482015260640161035e565b61057c600082610adb565b6105be5760405162461bcd60e51b815260206004820152601360248201527213dddb995c88185b1c9958591e481859191959606a1b604482015260640161035e565b600280549060006105ce8361105a565b9091555050604080516001600160a01b0383168152600160208201526000805160206111b3833981519152910161044b565b336000908152600160205260408120549081900361064d5760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b604482015260640161035e565b60008585858560025460405160200161066a959493929190611073565b60408051808303601f190181528282528051602091820120600081815260048352839020606085018452546001600160801b0381168552600160801b810467ffffffffffffffff16928501839052600160c01b900460ff169284019290925290925015806106ef57504267ffffffffffffffff16816020015167ffffffffffffffff16105b156107595760035461070190426110a7565b67ffffffffffffffff16602082810182905260008084526040808501919091528051858152918201929092527fdba396e3f86ba92c12e944cda2d787eea52a24f6babcbd54c8ffb2d369bca7c9910160405180910390a15b80516001841b9081166001600160801b03166000036107a05781516001600160801b038083169116178252604082018051600191906107999083906110ba565b60ff169052505b6107b0826040015160ff16610c95565b156108575760008381526004602090815260409182902080546001600160c81b03191690558151601f8801829004820281018201909252868252610813918a918a91908a908a9081908401838280828437600092019190915250610ce292505050565b7fc75495e0be082158e5855c35d211235055bf668ec3933eb9f3cf757c6493ee6d838989898960405161084a9594939291906110d3565b60405180910390a16108bd565b60008381526004602090815260409182902084518154928601519386015160ff16600160c01b0260ff60c01b1967ffffffffffffffff909516600160801b026001600160c01b03199094166001600160801b039092169190911792909217929092161790555b5050505050505050565b60606000800180548060200260200160405190810160405280929190818152602001828054801561092157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610903575b5050505050905090565b30331461094a5760405162461bcd60e51b815260040161035e90611015565b6001600160a01b03811661098f5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640161035e565b61099b60008383610d80565b610a0d5760405162461bcd60e51b815260206004820152603960248201527f63757272656e744164647265737320646f6573206e6f74206578697374206f7260448201527f206e65774164647265737320616c726561647920657869737400000000000000606482015260840161035e565b604080516001600160a01b0384168152600060208201526000805160206111b3833981519152910160405180910390a1604080516001600160a01b0383168152600160208201526000805160206111b3833981519152910160405180910390a15050565b303314610a905760405162461bcd60e51b815260040161035e90611015565b62015180811015610ad65760405162461bcd60e51b815260206004820152601060248201526f151bdbc81cda1bdc9d081c195c9a5bd960821b604482015260640161035e565b600355565b6001600160a01b0381166000908152600183016020526040812054610b4557508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b03861690811790915585549082528286019093526040902091909155610b49565b5060005b92915050565b5490565b6001600160a01b03811660009081526001830160205260408120548015610c8b576000610b81600183611122565b8554909150600090610b9590600190611122565b90506000866000018281548110610bae57610bae611135565b60009182526020909120015487546001600160a01b0390911691508190889085908110610bdd57610bdd611135565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055610c118360016110a7565b6001600160a01b03821660009081526001890160205260409020558654879080610c3d57610c3d61114b565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220919091559450610b499350505050565b6000915050610b49565b60055460009081610ca4815490565b9050811580610cb257508082115b15610cd857610cc2600282611161565b610ccd9060016110a7565b909310159392505050565b5090911015919050565b6000836001600160a01b03168383604051610cfd9190611183565b60006040518083038185875af1925050503d8060008114610d3a576040519150601f19603f3d011682016040523d82523d6000602084013e610d3f565b606091505b50509050806102d75760405162461bcd60e51b815260206004820152600d60248201526c22bc32b1baba329032b93937b960991b604482015260640161035e565b6001600160a01b038281166000908152600185016020526040808220549284168252812054909190151580610db3575080155b15610dc2576000915050610e2c565b8285610dcf600184611122565b81548110610ddf57610ddf611135565b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790558583168252600188810190915260408083209490945591861681529182209190915590505b9392505050565b80356001600160a01b0381168114610e4a57600080fd5b919050565b60008083601f840112610e6157600080fd5b50813567ffffffffffffffff811115610e7957600080fd5b602083019150836020828501011115610e9157600080fd5b9250929050565b600080600080600060808688031215610eb057600080fd5b610eb986610e33565b9450610ec760208701610e33565b935060408601359250606086013567ffffffffffffffff811115610eea57600080fd5b610ef688828901610e4f565b969995985093965092949392505050565b600060208284031215610f1957600080fd5b610e2c82610e33565b600060208284031215610f3457600080fd5b5035919050565b60008060008060608587031215610f5157600080fd5b610f5a85610e33565b935060208501359250604085013567ffffffffffffffff811115610f7d57600080fd5b610f8987828801610e4f565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b81811015610fd65783516001600160a01b031683529284019291840191600101610fb1565b50909695505050505050565b60008060408385031215610ff557600080fd5b610ffe83610e33565b915061100c60208401610e33565b90509250929050565b60208082526015908201527413db9b1e481b5d5b1d1a5cda59c8185b1b1bddd959605a1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001820161106c5761106c611044565b5060010190565b6bffffffffffffffffffffffff198660601b1681528460148201528284603483013760349201918201526054019392505050565b80820180821115610b4957610b49611044565b60ff8181168382160190811115610b4957610b49611044565b8581526001600160a01b0385166020820152604081018490526080606082018190528101829052818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b81810381811115610b4957610b49611044565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008261117e57634e487b7160e01b600052601260045260246000fd5b500490565b6000825160005b818110156111a4576020818601810151858301520161118a565b50600092019182525091905056fe5501576e82029b0850ec7c74ac25b5a46839bf523772a6ac579cc55b092281c8a26469706673582212205bc8246284b19a2fc8bec1da8db6b2ba4cd940c8f28c417b883806d34cd7da1164736f6c634300081100330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000004cc3a18209517a09f472639551357db80a17412b000000000000000000000000cb9539df5a8617c4b39105f3d3a614ab72b94f5b000000000000000000000000c9bea9379a8fade01240ee583535fac713b7101400000000000000000000000012d61e143e780ce904ce16f764668511708b2e31000000000000000000000000600360f031a22213522329c41ead9f0a4d6f37ff000000000000000000000000af329a2986d7f78991ab5aedad6c7c3a2bc760a5
Deployed ByteCode
0x6080604052600436106100e15760003560e01c80637dd0dd161161007f5780638943ec02116100595780638943ec02146102bc578063a0e67e2b146102dd578063c1d74a4c146102ff578063d7a52fa91461031f57600080fd5b80637dd0dd16146102025780638638fb5a1461028757806386cbaed81461029c57600080fd5b8063173825d9116100bb578063173825d91461018a57806321407e53146101ac5780632203d796146101c25780637065cb48146101e257600080fd5b806313e26d58146100ed578063150b7a0214610116578063163d262f1461017457600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010360055481565b6040519081526020015b60405180910390f35b34801561012257600080fd5b5061015b610131366004610e98565b7f150b7a023d4804d13e8c85fb27262cb750cf6ba9f9dd3bb30d90f482ceeb4b1f95945050505050565b6040516001600160e01b0319909116815260200161010d565b34801561018057600080fd5b5061010360025481565b34801561019657600080fd5b506101aa6101a5366004610f07565b61033f565b005b3480156101b857600080fd5b5061010360035481565b3480156101ce57600080fd5b506101aa6101dd366004610f22565b610456565b3480156101ee57600080fd5b506101aa6101fd366004610f07565b6104c3565b34801561020e57600080fd5b5061025661021d366004610f22565b6004602052600090815260409020546001600160801b03811690600160801b810467ffffffffffffffff1690600160c01b900460ff1683565b604080516001600160801b03909416845267ffffffffffffffff909216602084015260ff169082015260600161010d565b34801561029357600080fd5b50600054610103565b3480156102a857600080fd5b506101aa6102b7366004610f3b565b610600565b3480156102c857600080fd5b506101aa6102d7366004610f3b565b50505050565b3480156102e957600080fd5b506102f26108c7565b60405161010d9190610f95565b34801561030b57600080fd5b506101aa61031a366004610fe2565b61092b565b34801561032b57600080fd5b506101aa61033a366004610f22565b610a71565b3033146103675760405162461bcd60e51b815260040161035e90611015565b60405180910390fd5b600161037260005490565b116103bf5760405162461bcd60e51b815260206004820181905260248201527f52656d6f766520616c6c206f776e657273206973206e6f7420616c6c6f776564604482015260640161035e565b6103ca600082610b53565b61040d5760405162461bcd60e51b815260206004820152601460248201527313dddb995c88191bd95cc81b9bdd08195e1a5cdd60621b604482015260640161035e565b6002805490600061041d8361105a565b9091555050604080516001600160a01b0383168152600060208201526000805160206111b383398151915291015b60405180910390a150565b3033146104755760405162461bcd60e51b815260040161035e90611015565b6000548111156104be5760405162461bcd60e51b81526020600482015260146024820152735f6d696e526571756972656420746f6f2062696760601b604482015260640161035e565b600555565b3033146104e25760405162461bcd60e51b815260040161035e90611015565b6001600160a01b0381166105275760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640161035e565b607f61053260005490565b106105715760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206f776e65727360881b604482015260640161035e565b61057c600082610adb565b6105be5760405162461bcd60e51b815260206004820152601360248201527213dddb995c88185b1c9958591e481859191959606a1b604482015260640161035e565b600280549060006105ce8361105a565b9091555050604080516001600160a01b0383168152600160208201526000805160206111b3833981519152910161044b565b336000908152600160205260408120549081900361064d5760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b604482015260640161035e565b60008585858560025460405160200161066a959493929190611073565b60408051808303601f190181528282528051602091820120600081815260048352839020606085018452546001600160801b0381168552600160801b810467ffffffffffffffff16928501839052600160c01b900460ff169284019290925290925015806106ef57504267ffffffffffffffff16816020015167ffffffffffffffff16105b156107595760035461070190426110a7565b67ffffffffffffffff16602082810182905260008084526040808501919091528051858152918201929092527fdba396e3f86ba92c12e944cda2d787eea52a24f6babcbd54c8ffb2d369bca7c9910160405180910390a15b80516001841b9081166001600160801b03166000036107a05781516001600160801b038083169116178252604082018051600191906107999083906110ba565b60ff169052505b6107b0826040015160ff16610c95565b156108575760008381526004602090815260409182902080546001600160c81b03191690558151601f8801829004820281018201909252868252610813918a918a91908a908a9081908401838280828437600092019190915250610ce292505050565b7fc75495e0be082158e5855c35d211235055bf668ec3933eb9f3cf757c6493ee6d838989898960405161084a9594939291906110d3565b60405180910390a16108bd565b60008381526004602090815260409182902084518154928601519386015160ff16600160c01b0260ff60c01b1967ffffffffffffffff909516600160801b026001600160c01b03199094166001600160801b039092169190911792909217929092161790555b5050505050505050565b60606000800180548060200260200160405190810160405280929190818152602001828054801561092157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610903575b5050505050905090565b30331461094a5760405162461bcd60e51b815260040161035e90611015565b6001600160a01b03811661098f5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b604482015260640161035e565b61099b60008383610d80565b610a0d5760405162461bcd60e51b815260206004820152603960248201527f63757272656e744164647265737320646f6573206e6f74206578697374206f7260448201527f206e65774164647265737320616c726561647920657869737400000000000000606482015260840161035e565b604080516001600160a01b0384168152600060208201526000805160206111b3833981519152910160405180910390a1604080516001600160a01b0383168152600160208201526000805160206111b3833981519152910160405180910390a15050565b303314610a905760405162461bcd60e51b815260040161035e90611015565b62015180811015610ad65760405162461bcd60e51b815260206004820152601060248201526f151bdbc81cda1bdc9d081c195c9a5bd960821b604482015260640161035e565b600355565b6001600160a01b0381166000908152600183016020526040812054610b4557508154600180820184556000848152602080822090930180546001600160a01b0319166001600160a01b03861690811790915585549082528286019093526040902091909155610b49565b5060005b92915050565b5490565b6001600160a01b03811660009081526001830160205260408120548015610c8b576000610b81600183611122565b8554909150600090610b9590600190611122565b90506000866000018281548110610bae57610bae611135565b60009182526020909120015487546001600160a01b0390911691508190889085908110610bdd57610bdd611135565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055610c118360016110a7565b6001600160a01b03821660009081526001890160205260409020558654879080610c3d57610c3d61114b565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220919091559450610b499350505050565b6000915050610b49565b60055460009081610ca4815490565b9050811580610cb257508082115b15610cd857610cc2600282611161565b610ccd9060016110a7565b909310159392505050565b5090911015919050565b6000836001600160a01b03168383604051610cfd9190611183565b60006040518083038185875af1925050503d8060008114610d3a576040519150601f19603f3d011682016040523d82523d6000602084013e610d3f565b606091505b50509050806102d75760405162461bcd60e51b815260206004820152600d60248201526c22bc32b1baba329032b93937b960991b604482015260640161035e565b6001600160a01b038281166000908152600185016020526040808220549284168252812054909190151580610db3575080155b15610dc2576000915050610e2c565b8285610dcf600184611122565b81548110610ddf57610ddf611135565b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790558583168252600188810190915260408083209490945591861681529182209190915590505b9392505050565b80356001600160a01b0381168114610e4a57600080fd5b919050565b60008083601f840112610e6157600080fd5b50813567ffffffffffffffff811115610e7957600080fd5b602083019150836020828501011115610e9157600080fd5b9250929050565b600080600080600060808688031215610eb057600080fd5b610eb986610e33565b9450610ec760208701610e33565b935060408601359250606086013567ffffffffffffffff811115610eea57600080fd5b610ef688828901610e4f565b969995985093965092949392505050565b600060208284031215610f1957600080fd5b610e2c82610e33565b600060208284031215610f3457600080fd5b5035919050565b60008060008060608587031215610f5157600080fd5b610f5a85610e33565b935060208501359250604085013567ffffffffffffffff811115610f7d57600080fd5b610f8987828801610e4f565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b81811015610fd65783516001600160a01b031683529284019291840191600101610fb1565b50909695505050505050565b60008060408385031215610ff557600080fd5b610ffe83610e33565b915061100c60208401610e33565b90509250929050565b60208082526015908201527413db9b1e481b5d5b1d1a5cda59c8185b1b1bddd959605a1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001820161106c5761106c611044565b5060010190565b6bffffffffffffffffffffffff198660601b1681528460148201528284603483013760349201918201526054019392505050565b80820180821115610b4957610b49611044565b60ff8181168382160190811115610b4957610b49611044565b8581526001600160a01b0385166020820152604081018490526080606082018190528101829052818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b81810381811115610b4957610b49611044565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008261117e57634e487b7160e01b600052601260045260246000fd5b500490565b6000825160005b818110156111a4576020818601810151858301520161118a565b50600092019182525091905056fe5501576e82029b0850ec7c74ac25b5a46839bf523772a6ac579cc55b092281c8a26469706673582212205bc8246284b19a2fc8bec1da8db6b2ba4cd940c8f28c417b883806d34cd7da1164736f6c63430008110033