Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Execution
- Optimization enabled
- true
- Compiler version
- v0.8.25+commit.b61c2a91
- Optimization runs
- 800
- EVM Version
- paris
- Verified at
- 2024-10-31T15:23:26.595229Z
Constructor Arguments
0x00000000000000000000000082cb12995f4861d317a6c7c72917be3c243222a6
Arg [0] (address) : 0x82cb12995f4861d317a6c7c72917be3c243222a6
src/Execution.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.19; import {SignatureChecker} from "openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol"; import {Address} from "openzeppelin-contracts/contracts/utils/Address.sol"; import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; import {ECDSA} from "openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; import {SignatureQueue, SQState, MovementType, Movement, Call} from "./interfaces/IExecution.sol"; import {IFun} from "./interfaces/IFun.sol"; import {IPowerProxy} from "./interfaces/IPowerProxy.sol"; import {IERC1155Receiver} from "openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol"; import {EIP712} from "./info/EIP712.sol"; import {PowerProxy} from "./components/PowerProxy.sol"; import {Receiver} from "solady/accounts/Receiver.sol"; import "forge-std/console.sol"; /// @title Execution /// @author parseb contract Execution is EIP712, Receiver { using Address for address; using Strings for string; address public WillToken; IFun public WillWe; bytes4 internal constant EIP1271_MAGICVALUE = 0x1626ba7e; bytes4 internal constant EIP1271_MAGIC_VALUE_LEGACY = 0x20c13b0b; bytes32 public constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); bytes32 public constant MOVEMENT_TYPEHASH = keccak256( "Movement(uint8 category,address initiatior,address exeAccount,uint256 viaNode,uint256 expiresAt,bytes32 descriptionHash,bytes executedPayload)" ); /// errors error UninitQueue(); error ExpiredMovement(); error InvalidQueue(); error EmptyUnallowed(); error NotNodeMember(); error AlreadyInitialized(); error UnavailableState(); error ExpiredQueue(); error NotExeAccOwner(); error AlreadyHasEndpoint(); error NoMembersForNode(); error NoMovementType(); error AlreadySigned(); error LenErr(); error AlreadyInit(); error OnlyFun(); error NoSignatures(); error EXEC_SQInvalid(); error EXEC_NoType(); error EXEC_NoDescription(); error EXEC_ZeroLen(); error EXEC_A0sig(); error EXEC_OnlyMore(); error EXEC_OnlySigner(); error EXEC_exeQFail(); error EXEC_InProgress(); error EXEC_ActionIndexMismatch(); error EXEC_BadOwnerOrAuthType(); /// events event NewMovementCreated(bytes32 indexed movementHash, uint256 indexed nodeId); event EndpointCreatedForAgent(uint256 indexed nodeId, address endpoint, address agent); event WillWeSet(address implementation); event NewSignaturesSubmitted(bytes32 indexed queueHash); event QueueExecuted(uint256 indexed nodeId, bytes32 indexed queueHash); event SignatureRemoved(uint256 indexed nodeId, bytes32 indexed queueHash, address signer); event LatentActionRemoved(uint256 indexed nodeId, bytes32 indexed actionHash, uint256 index); /// @notice signature by hash mapping(bytes32 hash => SignatureQueue SigQueue) getSigQueueByHash; /// @notice initialized actions from node [node -> latentActionsOfNode[] | [0] valid start index, prevs. 0] mapping(uint256 => bytes32[]) latentActions; /// @notice stores node that ownes a particular execution agent authorisation mapping(address exeAccount => uint256 endpointOwner) engineOwner; /// @notice any one agent is allowed to have only one endpoint /// @notice stores agent signatures to prevent double signing | ( uint256(hash) - uint256(_msgSender() ) - signer can be simple or composed agent mapping(uint256 agentPlusNode => bool) hasEndpointOrInteraction; constructor(address WillToken_) { WillToken = WillToken_; DOMAIN_SEPARATOR = keccak256( abi.encode( EIP712_DOMAIN_TYPEHASH, keccak256(bytes("WillWe")), keccak256(bytes("1")), block.chainid, address(this) ) ); } function setWillWe(address implementation) external { if (address(WillWe) == address(0)) WillWe = IFun(implementation); if (msg.sender == WillToken) WillWe = IFun(implementation); emit WillWeSet(implementation); } function startMovement( address origin, uint8 typeOfMovement, uint256 nodeId, uint256 expiresInDays, address executingAccount, bytes32 descriptionHash, bytes memory data ) external virtual returns (bytes32 movementHash) { if (msg.sender != address(WillWe)) revert OnlyFun(); if (typeOfMovement > 2 || typeOfMovement == 0) revert NoMovementType(); if (!WillWe.isMember(origin, nodeId)) revert NotNodeMember(); if (((typeOfMovement * nodeId * expiresInDays) == 0)) revert EmptyUnallowed(); if (uint256(descriptionHash) == 0) revert EXEC_NoDescription(); if (executingAccount == address(0)) { executingAccount = createNodeEndpoint(origin, nodeId, typeOfMovement); engineOwner[executingAccount] = nodeId; } else { if (!(engineOwner[executingAccount] == nodeId)) revert NotExeAccOwner(); if ( IPowerProxy(executingAccount).owner() != address(this) || IPowerProxy(executingAccount).allowedAuthType() != typeOfMovement ) revert EXEC_BadOwnerOrAuthType(); } Movement memory M; M.initiatior = msg.sender; M.viaNode = nodeId; M.descriptionHash = descriptionHash; M.executedPayload = data; M.exeAccount = executingAccount; M.expiresAt = (expiresInDays * 1 days) + block.timestamp; M.category = typeOfMovement == 1 ? MovementType.AgentMajority : MovementType.EnergeticMajority; movementHash = hashMessage(M); latentActions[nodeId].push(movementHash); SignatureQueue memory SQ; SQ.state = SQState.Initialized; SQ.Action = M; if (getSigQueueByHash[movementHash].state != SQState.None) revert AlreadyInitialized(); getSigQueueByHash[movementHash] = SQ; emit NewMovementCreated(movementHash, nodeId); } function executeQueue(bytes32 queueHash) public virtual returns (bool success) { if (msg.sender != address(WillWe)) revert OnlyFun(); SignatureQueue memory SQ = validateQueue(queueHash); if (SQ.state != SQState.Valid) revert InvalidQueue(); if (SQ.Action.expiresAt <= block.timestamp) revert ExpiredMovement(); Movement memory M = SQ.Action; SQ.state = SQState.Executed; getSigQueueByHash[queueHash] = SQ; (success,) = (SQ.Action.exeAccount).call(M.executedPayload); if (!success) revert EXEC_exeQFail(); emit QueueExecuted(SQ.Action.viaNode, queueHash); } function submitSignatures(bytes32 queueHash, address[] memory signers, bytes[] memory signatures) external { if (msg.sender != address(WillWe)) revert OnlyFun(); SignatureQueue memory SQ = getSigQueueByHash[queueHash]; if (signatures.length < SQ.Sigs.length) revert EXEC_OnlyMore(); if (signers.length * signatures.length == 0) revert EXEC_ZeroLen(); if (signers.length != signatures.length) revert LenErr(); bytes32 structHash = hashMessage(SQ.Action); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, structHash)); uint256 validCount; for (uint256 i = 0; i < signers.length; i++) { if (signers[i] == address(0)) revert EXEC_A0sig(); if (hasEndpointOrInteraction[uint256(queueHash) - uint160(signers[i])]) { continue; } if (!(WillWe.isMember(signers[i], SQ.Action.viaNode))) { continue; } (uint8 v, bytes32 r, bytes32 s) = splitSignature(signatures[i]); address recovered = ecrecover(digest, v, r, s); if (recovered != signers[i]) continue; hasEndpointOrInteraction[uint256(queueHash) - uint160(signers[i])] = true; validCount++; } if (validCount > 0) { uint256 newSize = SQ.Signers.length + validCount; address[] memory newSigners = new address[](newSize); bytes[] memory newSignatures = new bytes[](newSize); for (uint256 i = 0; i < SQ.Signers.length; i++) { newSigners[i] = SQ.Signers[i]; newSignatures[i] = SQ.Sigs[i]; } uint256 j = SQ.Signers.length; for (uint256 i = 0; i < signers.length; i++) { if (hasEndpointOrInteraction[uint256(queueHash) - uint160(signers[i])]) { newSigners[j] = signers[i]; newSignatures[j] = signatures[i]; j++; } } getSigQueueByHash[queueHash].Signers = newSigners; getSigQueueByHash[queueHash].Sigs = newSignatures; } emit NewSignaturesSubmitted(queueHash); } function removeSignature(bytes32 queueHash, uint256 index, address signer) external { if (msg.sender != address(WillWe)) revert OnlyFun(); SignatureQueue memory SQ = getSigQueueByHash[queueHash]; if (SQ.Signers[index] != signer) revert EXEC_OnlySigner(); delete SQ.Sigs[index]; delete SQ.Signers[index]; getSigQueueByHash[queueHash] = SQ; hasEndpointOrInteraction[uint256(queueHash) - uint160(signer)] = false; emit SignatureRemoved(SQ.Action.viaNode, queueHash, signer); } function removeLatentAction(bytes32 actionHash, uint256 index) external { SignatureQueue memory SQ = getSigQueueByHash[actionHash]; if (SQ.Action.expiresAt > block.timestamp) SQ.state = SQState.Stale; if (SQ.state == SQState.Initialized || SQ.state == SQState.Valid) revert EXEC_InProgress(); if (latentActions[SQ.Action.viaNode][index] != actionHash) revert EXEC_ActionIndexMismatch(); delete latentActions[SQ.Action.viaNode][index]; if (uint256(latentActions[SQ.Action.viaNode][0]) > index) latentActions[SQ.Action.viaNode][0] = bytes32(index); getSigQueueByHash[actionHash] = SQ; emit LatentActionRemoved(SQ.Action.viaNode, actionHash, index); } function createEndpointForOwner(address origin, uint256 nodeId, address owner) external returns (address endpoint) { if ((msg.sender != address(WillWe) && owner != address(this))) revert OnlyFun(); if (!WillWe.isMember(origin, nodeId) && owner != address(this)) revert NotNodeMember(); if (hasEndpointOrInteraction[nodeId + uint160(bytes20(owner))]) revert AlreadyHasEndpoint(); hasEndpointOrInteraction[nodeId + uint160(bytes20(owner))] = true; endpoint = createNodeEndpoint(origin, nodeId, 3); emit EndpointCreatedForAgent(nodeId, endpoint, owner); } function createNodeEndpoint(address originOrNode, uint256 endpointOwner_, uint8 consensusType) internal returns (address endpoint) { if (msg.sig == this.createEndpointForOwner.selector) { endpoint = spawnNodeEndpoint(originOrNode, 3); engineOwner[endpoint] = originOrNode == address(this) ? endpointOwner_ : uint160(originOrNode); } else { endpoint = spawnNodeEndpoint(address(this), consensusType); engineOwner[endpoint] = endpointOwner_; } WillWe.localizeEndpoint(endpoint, endpointOwner_, originOrNode); } function spawnNodeEndpoint(address proxyOwner_, uint8 authType) private returns (address) { return address(new PowerProxy(proxyOwner_, authType)); } function validateQueue(bytes32 sigHash) internal returns (SignatureQueue memory SQM) { SQM = getSigQueueByHash[sigHash]; if (SQM.Action.expiresAt <= block.timestamp) { SQM.state = SQState.Stale; getSigQueueByHash[sigHash] = SQM; } bytes32 hashedOne = hashMovement(SQM.Action); if (!isQueueValid(hashedOne)) revert EXEC_SQInvalid(); SQM.state = SQState.Valid; getSigQueueByHash[sigHash] = SQM; } function isQueueValid(bytes32 sigHash) public view returns (bool) { SignatureQueue memory SQM = getSigQueueByHash[sigHash]; if (SQM.Action.category == MovementType.Revert) return false; if (SQM.state == SQState.Valid) return true; if (SQM.state == SQState.Stale) return false; if (SQM.state != SQState.Initialized) return false; if (SQM.Signers.length == 0) return false; if (SQM.Signers.length != SQM.Sigs.length) return false; uint256 i; uint256 power; address[] memory signers = SQM.Signers; bytes[] memory signatures = SQM.Sigs; bytes32 signedHash = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, sigHash)); for (i; i < signatures.length; ++i) { if (signers[i] == address(0)) continue; if (!SignatureChecker.isValidSignatureNow(signers[i], signedHash, signatures[i])) return false; power = (SQM.Action.category == MovementType.EnergeticMajority) ? power + WillWe.balanceOf(signers[i], SQM.Action.viaNode) : power + 1; } if (power > 0) { if (SQM.Action.category == MovementType.EnergeticMajority) { return (power > ((WillWe.totalSupply(SQM.Action.viaNode) / 2))); } if (SQM.Action.category == MovementType.AgentMajority) { return (power > ((WillWe.allMembersOf(SQM.Action.viaNode).length / 2))); } } return false; } function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) { if (getSigQueueByHash[_hash].state == SQState.Valid) return EIP1271_MAGICVALUE; } /// @notice retrieves the node or agent that owns the execution account /// @param endpointAddress execution account for which to retrieve owner /// @dev in case of user-driven endpoints the returned value is uint160(address of endpoint creator) function endpointOwner(address endpointAddress) public view returns (uint256) { return engineOwner[endpointAddress]; } function getSigQueue(bytes32 hash_) public view returns (SignatureQueue memory) { return getSigQueueByHash[hash_]; } function hashMovement(Movement memory movement) public pure returns (bytes32) { return keccak256( abi.encode( MOVEMENT_TYPEHASH, movement.category, movement.initiatior, movement.exeAccount, movement.viaNode, movement.expiresAt, movement.descriptionHash, keccak256(movement.executedPayload) ) ); } function splitSignature(bytes memory sig) internal pure returns (uint8 v, bytes32 r, bytes32 s) { require(sig.length == 65, "Invalid signature length"); assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } if (v < 27) { v += 27; } require(v == 27 || v == 28, "Invalid signature 'v' value"); } }
lib/forge-std/src/console.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; /// @solidity memory-safe-assembly assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); } function logUint(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); } function log(uint p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); } function log(uint p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); } function log(uint p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); } function log(string memory p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); } function log(uint p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); } function log(uint p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); } function log(uint p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); } function log(uint p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); } function log(uint p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); } function log(uint p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); } function log(uint p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); } function log(uint p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); } function log(uint p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); } function log(uint p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); } function log(uint p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); } function log(uint p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); } function log(uint p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); } function log(uint p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); } function log(uint p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); } function log(string memory p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); } function log(string memory p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); } function log(string memory p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); } function log(string memory p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); } function log(bool p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); } function log(bool p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); } function log(bool p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); } function log(address p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); } function log(address p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); } function log(address p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * * _Available since v4.1._ */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with _data */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); }
lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
lib/openzeppelin-contracts/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
lib/openzeppelin-contracts/contracts/utils/Strings.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol) pragma solidity ^0.8.0; import "./ECDSA.sol"; import "../../interfaces/IERC1271.sol"; /** * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like * Argent and Gnosis Safe. * * _Available since v4.1._ */ library SignatureChecker { /** * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`. * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) { (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature); return (error == ECDSA.RecoverError.NoError && recovered == signer) || isValidERC1271SignatureNow(signer, hash, signature); } /** * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated * against the signer smart contract using ERC1271. * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidERC1271SignatureNow( address signer, bytes32 hash, bytes memory signature ) internal view returns (bool) { (bool success, bytes memory result) = signer.staticcall( abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature) ); return (success && result.length >= 32 && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)); } }
lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
lib/openzeppelin-contracts/contracts/utils/math/Math.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
lib/solady/src/accounts/Receiver.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Receiver mixin for ETH and safe-transferred ERC721 and ERC1155 tokens. /// @author Solady (https://github.com/Vectorized/solady/blob/main/src/accounts/Receiver.sol) /// /// @dev Note: /// - Handles all ERC721 and ERC1155 token safety callbacks. /// - Collapses function table gas overhead and code size. /// - Utilizes fallback so unknown calldata will pass on. abstract contract Receiver { /// @dev For receiving ETH. receive() external payable virtual {} /// @dev Fallback function with the `receiverFallback` modifier. fallback() external payable virtual receiverFallback {} /// @dev Modifier for the fallback function to handle token callbacks. modifier receiverFallback() virtual { /// @solidity memory-safe-assembly assembly { let s := shr(224, calldataload(0)) // 0x150b7a02: `onERC721Received(address,address,uint256,bytes)`. // 0xf23a6e61: `onERC1155Received(address,address,uint256,uint256,bytes)`. // 0xbc197c81: `onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)`. if or(eq(s, 0x150b7a02), or(eq(s, 0xf23a6e61), eq(s, 0xbc197c81))) { mstore(0x20, s) // Store `msg.sig`. return(0x3c, 0x20) // Return `msg.sig`. } } _; } }
src/components/PowerProxy.sol
pragma solidity ^0.8.19; import {Receiver} from "solady/accounts/Receiver.sol"; import {IPowerProxy} from "../interfaces/IPowerProxy.sol"; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ /// @author Michael Elliot <mike@makerdao.com> /// @author Joshua Levine <joshua@makerdao.com> /// @author Nick Johnson <arachnid@notdot.net> /// @author OpenZeppelin OpenZeppelin.com /// --------------------------------------- /// @author parseb.eth @ github.com/parseb /// @notice A simple authenticated proxy. A mashup of (MakerDAO) MulticallV2 and simple (OpenZeppelin) proxy. contract PowerProxy is Receiver { address public owner; address public implementation; /// @notice EIP 127 signature store mapping(bytes32 => bool) isSignedHash; /// @notice Stores execution authorisation type. uint8 public immutable allowedAuthType; constructor(address proxyOwner_, uint8 consensusType_) { owner = proxyOwner_; allowedAuthType = consensusType_; } struct Call { address target; bytes callData; } struct Result { bool success; bytes returnData; } error noFallback(); error NotOwner(); error Multicall2(); function tryAggregate(bool requireSuccess, Call[] calldata calls) public returns (Result[] memory returnData) { if (msg.sender != owner) revert NotOwner(); returnData = new Result[](calls.length); for (uint256 i = 0; i < calls.length; i++) { (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData); if (requireSuccess && (!success)) revert Multicall2(); returnData[i] = Result(success, ret); } } function setImplementation(address implementation_) external { if (msg.sender != owner) revert NotOwner(); if (implementation_ != implementation) implementation = implementation_; } function setOwner(address owner_) external { if (msg.sender != owner) revert NotOwner(); owner = owner_; } function setSignedHash(bytes32 hash_) external { if (msg.sender != owner) revert NotOwner(); isSignedHash[hash_] = !isSignedHash[hash_]; } function isValidSignature(bytes32 hash_, bytes calldata _signature) external view returns (bytes4) { if (isSignedHash[hash_]) return 0x1626ba7e; } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable override receiverFallback { if (implementation == address(0)) revert noFallback(); address i; assembly { i := sload(implementation.slot) // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), i, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } function onERC1155Received(address operator, address from, uint256 id, uint256 value, bytes calldata data) external pure returns (bytes4) { return 0xf23a6e61; } }
src/info/EIP712.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import {Movement, MovementType, SQState, SignatureQueue, Call} from "../interfaces/IExecution.sol"; // EIP712 domain separator struct EIP712Domain { string name; string version; uint256 chainId; address verifyingContract; bytes32 salt; } contract EIP712 { // EIP712 domain separator hash bytes32 internal DOMAIN_SEPARATOR; bytes32 internal immutable SALT; // EIP712 domain separator setup constructor() { SALT = keccak256(abi.encodePacked(block.timestamp, blockhash(block.number - 1), "SugarySalts")); DOMAIN_SEPARATOR = hashDomain( EIP712Domain({ name: "BagBok", version: "1", chainId: block.chainid, verifyingContract: address(this), salt: SALT }) ); } function hashDomain(EIP712Domain memory domain) public pure returns (bytes32) { return keccak256( abi.encode( keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)" ), keccak256(bytes(domain.name)), keccak256(bytes(domain.version)), domain.chainId, domain.verifyingContract, domain.salt ) ); } function hashMessage(Movement memory movement) public pure returns (bytes32) { return keccak256( abi.encode( keccak256( "Movement(uint8 category,address initiatior,address exeAccount,uint256 viaNode,uint256 expiresAt,bytes32 descriptionHash,bytes executedPayload)" ), movement.category, movement.initiatior, movement.exeAccount, movement.viaNode, movement.expiresAt, movement.descriptionHash, keccak256(movement.executedPayload) ) ); } function verifyMessage(Movement memory movement, uint8 v, bytes32 r, bytes32 s, address expectedAddress) public view returns (bool) { bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hashMessage(movement))); address recoveredAddress = ecrecover(digest, v, r, s); return (recoveredAddress == expectedAddress); } }
src/interfaces/IExecution.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.3; enum SQState { None, Initialized, Valid, Executed, Stale } enum MovementType { Revert, AgentMajority, EnergeticMajority } struct Call { address target; bytes callData; } struct Movement { MovementType category; address initiatior; address exeAccount; uint256 viaNode; uint256 expiresAt; bytes32 descriptionHash; bytes executedPayload; } struct SignatureQueue { SQState state; Movement Action; address[] Signers; bytes[] Sigs; bytes32 exeSig; } struct UserSignal { string[2][] MembraneInflation; string[] lastRedistSignal; } struct NodeState { string[9] basicInfo; // [nodeId, inflation, balanceAnchor, balanceBudget, value, membraneId, balanceOfUser, childParentEligibilityPerSec, lastParentRedistribution ] string membraneMeta; address[] membersOfNode; string[] childrenNodes; string[] rootPath; UserSignal[] signals; } interface IExecution { function createEndpointForOwner(address origin, uint256 nodeId_, address owner) external returns (address endpoint); function executeQueue(bytes32 SignatureQueueHash_) external returns (bool s); function submitSignatures(bytes32 sigHash, address[] memory signers, bytes[] memory signatures) external; function startMovement( address origin, uint8 typeOfMovement, uint256 node_, uint256 expiresInDays, address executingAccount, bytes32 descriptionHash, bytes memory data ) external returns (bytes32 movementHash); function setWillWe(address WillWeImplementationAddress) external; /// View function isQueueValid(bytes32 sigHash) external view returns (bool); function FoundingAgent() external returns (address); function WillToken() external view returns (address); function getSigQueue(bytes32 hash_) external view returns (SignatureQueue memory); /// @notice retrieves the node or agent that owns the execution account /// @param endpointAddress execution account for which to retrieve owner /// @dev in case of user-driven endpoints the returned value is uint160( address of endpoint creator ) function endpointOwner(address endpointAddress) external view returns (uint256); function isValidSignature(bytes32 _hash, bytes memory _signature) external view returns (bytes4); function hashMessage(Movement memory movement) external view returns (bytes32); //// cleanup functions function removeSignature(bytes32 sigHash_, uint256 index_, address who_) external; function removeLatentAction(bytes32 actionHash_, uint256 index) external; }
src/interfaces/IFun.sol
// SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.3; import {IERC1155} from "openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol"; import {IExecution, SignatureQueue, NodeState} from "./IExecution.sol"; interface IFun is IERC1155, IExecution { function spawnRootBranch(address fungible20_) external returns (uint256 fID); function spawnBranch(uint256 fid_) external returns (uint256 newID); function spawnBranchWithMembrane(uint256 fid_, uint256 membraneID_) external returns (uint256 newID); function mintMembership(uint256 fid_, address to_) external returns (uint256 mID); function membershipEnforce(address target, uint256 fid_) external returns (bool s); function burn(uint256 fid_, uint256 amount_) external; function allMembersOf(uint256 fid_) external view returns (address[] memory); function mint(uint256 fid_, uint256 amount_) external; function toID(address x) external view returns (uint256); function toAddress(uint256 x) external view returns (address); function isMember(address whoabout_, uint256 whereabout_) external view returns (bool); function getInUseMemberaneID(uint256 fid_) external view returns (uint256 membraneID_); function getMembraneOf(uint256 fid_) external view returns (uint256); function getChildrenOf(uint256 fid_) external view returns (uint256[] memory); function getParentOf(uint256 fid_) external view returns (uint256); function membershipID(uint256 fid_) external pure returns (uint256); function getRootId(uint256 fid_) external view returns (uint256); function getRootToken(uint256 fid_) external view returns (address); function fungo() external returns (address); function createEndpointForOwner(uint256 nodeId_, address owner) external returns (address endpoint); function localizeEndpoint(address endpointAddress, uint256 endpointParent_, address endpointOwner_) external; function getSigQueue(bytes32 hash_) external view returns (SignatureQueue memory); function totalSupply(uint256 nodeId) external view returns (uint256); function executionEngineAddress() external view returns (address); function rule() external; function Will() external view returns (address); function getUserInteractions(address user_) external view returns (uint256[][2] memory); function removeSignature(bytes32 sigHash_, uint256 index_) external; function inParentDenomination(uint256 amt_, uint256 id_) external view returns (uint256); function getFidPath(uint256 fid_) external view returns (uint256[] memory fids); function burnPath(uint256 target_, uint256 amount) external; function mintPath(uint256 target_, uint256 amount) external; function sendSignal(uint256 targetNode_, uint256[] memory signals) external; function initSelfControl() external returns (address controlingAgent); //// Data function getNodeData(uint256 n) external view returns (NodeState memory N); function getNodes(uint256[] memory nodeIds) external view returns (NodeState[] memory nodes); function getAllNodesForRoot(address rootAddress, address userIfAny) external view returns (NodeState[] memory nodes); }
src/interfaces/IPowerProxy.sol
pragma solidity ^0.8.19; /// @author parseb.eth @ github.com/parseb interface IPowerProxy { /// @notice Struct representing a call to be made in the tryAggregate function struct Call { address target; bytes callData; } /// @notice Struct representing the result of a call made in the tryAggregate function struct Result { bool success; bytes returnData; } /// @notice Thrown when the fallback function is called but no implementation is set error noFallback(); /// @notice Thrown when a function is called by an address that is not the owner error NotOwner(); /// @notice Thrown when a call in the tryAggregate function fails and requireSuccess is true error Multicall2(); /// @notice Returns the address that is authorized to use this proxy function owner() external view returns (address); /// @notice Returns the address of the implementation behind the proxy function implementation() external view returns (address); /// @notice Returns the execution authorization type function allowedAuthType() external view returns (uint8); /// @notice Executes a batch of calls and returns the results /// @param requireSuccess If true, the function will revert if any call fails /// @param calls The batch of calls to execute /// @return returnData The results of the calls function tryAggregate(bool requireSuccess, Call[] calldata calls) external returns (Result[] memory returnData); /// @notice Sets the address of the implementation behind the proxy /// @param implementation_ The address of the new implementation function setImplementation(address implementation_) external; /// @notice Sets the address that is authorized to use this proxy /// @param owner_ The address of the new owner function setOwner(address owner_) external; /// @notice Checks if a given hash is a valid signature /// @param hash_ The hash to check /// @param _signature The signature to check /// @return The magic value 0x1626ba7e if the hash is a valid signature, 0 otherwise function isValidSignature(bytes32 hash_, bytes calldata _signature) external view returns (bytes4); /// @notice Sets the validity of a given hash /// @param hash_ The hash to set the validity of function setSignedHash(bytes32 hash_) external; }
Compiler Settings
{"viaIR":false,"remappings":["openzeppelin-contracts/token/=lib/openzeppelin-contracts/contracts/token/","openzeppelin-contracts/contracts/=lib/openzeppelin-contracts/contracts/","@solady/=lib/solady/src/","src/vendor/interfaces/=lib/optimism/packages/contracts-bedrock/src/vendor/interfaces/","@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/","ERC20ASG/=lib/ERC20ASG/","automate/=lib/optimism/packages/contracts-bedrock/lib/automate/contracts/","ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/halmos-cheatcodes/src/","kontrol-cheatcodes/=lib/optimism/packages/contracts-bedrock/lib/kontrol-cheatcodes/src/","lib-keccak/=lib/optimism/packages/contracts-bedrock/lib/lib-keccak/contracts/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts-v5/=lib/optimism/packages/contracts-bedrock/lib/openzeppelin-contracts-v5/","openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/","openzeppelin/=lib/openzeppelin-contracts/contracts/","optimism/=lib/optimism/","prb-test/=lib/optimism/packages/contracts-bedrock/lib/automate/lib/prb-test/src/","safe-contracts/=lib/optimism/packages/contracts-bedrock/lib/safe-contracts/contracts/","solady/=lib/solady/src/","solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/","solmate/=lib/optimism/packages/contracts-bedrock/lib/solmate/src/"],"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","storageLayout"],"":["ast"]}},"optimizer":{"runs":800,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"WillToken_","internalType":"address"}]},{"type":"error","name":"AlreadyHasEndpoint","inputs":[]},{"type":"error","name":"AlreadyInit","inputs":[]},{"type":"error","name":"AlreadyInitialized","inputs":[]},{"type":"error","name":"AlreadySigned","inputs":[]},{"type":"error","name":"EXEC_A0sig","inputs":[]},{"type":"error","name":"EXEC_ActionIndexMismatch","inputs":[]},{"type":"error","name":"EXEC_BadOwnerOrAuthType","inputs":[]},{"type":"error","name":"EXEC_InProgress","inputs":[]},{"type":"error","name":"EXEC_NoDescription","inputs":[]},{"type":"error","name":"EXEC_NoType","inputs":[]},{"type":"error","name":"EXEC_OnlyMore","inputs":[]},{"type":"error","name":"EXEC_OnlySigner","inputs":[]},{"type":"error","name":"EXEC_SQInvalid","inputs":[]},{"type":"error","name":"EXEC_ZeroLen","inputs":[]},{"type":"error","name":"EXEC_exeQFail","inputs":[]},{"type":"error","name":"EmptyUnallowed","inputs":[]},{"type":"error","name":"ExpiredMovement","inputs":[]},{"type":"error","name":"ExpiredQueue","inputs":[]},{"type":"error","name":"InvalidQueue","inputs":[]},{"type":"error","name":"LenErr","inputs":[]},{"type":"error","name":"NoMembersForNode","inputs":[]},{"type":"error","name":"NoMovementType","inputs":[]},{"type":"error","name":"NoSignatures","inputs":[]},{"type":"error","name":"NotExeAccOwner","inputs":[]},{"type":"error","name":"NotNodeMember","inputs":[]},{"type":"error","name":"OnlyFun","inputs":[]},{"type":"error","name":"UnavailableState","inputs":[]},{"type":"error","name":"UninitQueue","inputs":[]},{"type":"event","name":"EndpointCreatedForAgent","inputs":[{"type":"uint256","name":"nodeId","internalType":"uint256","indexed":true},{"type":"address","name":"endpoint","internalType":"address","indexed":false},{"type":"address","name":"agent","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"LatentActionRemoved","inputs":[{"type":"uint256","name":"nodeId","internalType":"uint256","indexed":true},{"type":"bytes32","name":"actionHash","internalType":"bytes32","indexed":true},{"type":"uint256","name":"index","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"NewMovementCreated","inputs":[{"type":"bytes32","name":"movementHash","internalType":"bytes32","indexed":true},{"type":"uint256","name":"nodeId","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"NewSignaturesSubmitted","inputs":[{"type":"bytes32","name":"queueHash","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"QueueExecuted","inputs":[{"type":"uint256","name":"nodeId","internalType":"uint256","indexed":true},{"type":"bytes32","name":"queueHash","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"SignatureRemoved","inputs":[{"type":"uint256","name":"nodeId","internalType":"uint256","indexed":true},{"type":"bytes32","name":"queueHash","internalType":"bytes32","indexed":true},{"type":"address","name":"signer","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"WillWeSet","inputs":[{"type":"address","name":"implementation","internalType":"address","indexed":false}],"anonymous":false},{"type":"fallback","stateMutability":"payable"},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"EIP712_DOMAIN_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"MOVEMENT_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"WillToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IFun"}],"name":"WillWe","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"endpoint","internalType":"address"}],"name":"createEndpointForOwner","inputs":[{"type":"address","name":"origin","internalType":"address"},{"type":"uint256","name":"nodeId","internalType":"uint256"},{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"endpointOwner","inputs":[{"type":"address","name":"endpointAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"executeQueue","inputs":[{"type":"bytes32","name":"queueHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct SignatureQueue","components":[{"type":"uint8","name":"state","internalType":"enum SQState"},{"type":"tuple","name":"Action","internalType":"struct Movement","components":[{"type":"uint8","name":"category","internalType":"enum MovementType"},{"type":"address","name":"initiatior","internalType":"address"},{"type":"address","name":"exeAccount","internalType":"address"},{"type":"uint256","name":"viaNode","internalType":"uint256"},{"type":"uint256","name":"expiresAt","internalType":"uint256"},{"type":"bytes32","name":"descriptionHash","internalType":"bytes32"},{"type":"bytes","name":"executedPayload","internalType":"bytes"}]},{"type":"address[]","name":"Signers","internalType":"address[]"},{"type":"bytes[]","name":"Sigs","internalType":"bytes[]"},{"type":"bytes32","name":"exeSig","internalType":"bytes32"}]}],"name":"getSigQueue","inputs":[{"type":"bytes32","name":"hash_","internalType":"bytes32"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"hashDomain","inputs":[{"type":"tuple","name":"domain","internalType":"struct EIP712Domain","components":[{"type":"string","name":"name","internalType":"string"},{"type":"string","name":"version","internalType":"string"},{"type":"uint256","name":"chainId","internalType":"uint256"},{"type":"address","name":"verifyingContract","internalType":"address"},{"type":"bytes32","name":"salt","internalType":"bytes32"}]}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"hashMessage","inputs":[{"type":"tuple","name":"movement","internalType":"struct Movement","components":[{"type":"uint8","name":"category","internalType":"enum MovementType"},{"type":"address","name":"initiatior","internalType":"address"},{"type":"address","name":"exeAccount","internalType":"address"},{"type":"uint256","name":"viaNode","internalType":"uint256"},{"type":"uint256","name":"expiresAt","internalType":"uint256"},{"type":"bytes32","name":"descriptionHash","internalType":"bytes32"},{"type":"bytes","name":"executedPayload","internalType":"bytes"}]}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"hashMovement","inputs":[{"type":"tuple","name":"movement","internalType":"struct Movement","components":[{"type":"uint8","name":"category","internalType":"enum MovementType"},{"type":"address","name":"initiatior","internalType":"address"},{"type":"address","name":"exeAccount","internalType":"address"},{"type":"uint256","name":"viaNode","internalType":"uint256"},{"type":"uint256","name":"expiresAt","internalType":"uint256"},{"type":"bytes32","name":"descriptionHash","internalType":"bytes32"},{"type":"bytes","name":"executedPayload","internalType":"bytes"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isQueueValid","inputs":[{"type":"bytes32","name":"sigHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes4","name":"","internalType":"bytes4"}],"name":"isValidSignature","inputs":[{"type":"bytes32","name":"_hash","internalType":"bytes32"},{"type":"bytes","name":"_signature","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeLatentAction","inputs":[{"type":"bytes32","name":"actionHash","internalType":"bytes32"},{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeSignature","inputs":[{"type":"bytes32","name":"queueHash","internalType":"bytes32"},{"type":"uint256","name":"index","internalType":"uint256"},{"type":"address","name":"signer","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWillWe","inputs":[{"type":"address","name":"implementation","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"movementHash","internalType":"bytes32"}],"name":"startMovement","inputs":[{"type":"address","name":"origin","internalType":"address"},{"type":"uint8","name":"typeOfMovement","internalType":"uint8"},{"type":"uint256","name":"nodeId","internalType":"uint256"},{"type":"uint256","name":"expiresInDays","internalType":"uint256"},{"type":"address","name":"executingAccount","internalType":"address"},{"type":"bytes32","name":"descriptionHash","internalType":"bytes32"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"submitSignatures","inputs":[{"type":"bytes32","name":"queueHash","internalType":"bytes32"},{"type":"address[]","name":"signers","internalType":"address[]"},{"type":"bytes[]","name":"signatures","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"verifyMessage","inputs":[{"type":"tuple","name":"movement","internalType":"struct Movement","components":[{"type":"uint8","name":"category","internalType":"enum MovementType"},{"type":"address","name":"initiatior","internalType":"address"},{"type":"address","name":"exeAccount","internalType":"address"},{"type":"uint256","name":"viaNode","internalType":"uint256"},{"type":"uint256","name":"expiresAt","internalType":"uint256"},{"type":"bytes32","name":"descriptionHash","internalType":"bytes32"},{"type":"bytes","name":"executedPayload","internalType":"bytes"}]},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"},{"type":"address","name":"expectedAddress","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x60a060405234801561001057600080fd5b5060405161524b38038061524b83398101604081905261002f9161027d565b4261003b6001436102ad565b4060405160200161006a92919091825260208201526a53756761727953616c747360a81b6040820152604b0190565b60408051601f198184030181528282528051602091820120608090815260e084018352600660a0850190815265426167426f6b60d01b60c086015284528251808401845260018152603160f81b818401529184019190915246918301919091523060608301528051908201526100df906101d5565b600055600180546001600160a01b0319166001600160a01b038316178155604080518082018252600681526557696c6c576560d01b60209182015281518083018352928352603160f81b9281019290925280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f928101929092527f9002a7a6959b8c6477c2ff370c0ca5c2e3f0a2ac79e9d5e999ea2fe6137f812c908201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160408051601f198184030181529190528051602090910120600055506102d4565b60007fd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472826000015180519060200120836020015180519060200120846040015185606001518660800151604051602001610260969594939291909586526020860194909452604085019290925260608401526001600160a01b0316608083015260a082015260c00190565b604051602081830303815290604052805190602001209050919050565b60006020828403121561028f57600080fd5b81516001600160a01b03811681146102a657600080fd5b9392505050565b818103818111156102ce57634e487b7160e01b600052601160045260246000fd5b92915050565b608051614f5f6102ec60003960005050614f5f6000f3fe6080604052600436106101485760003560e01c806390ef12cd116100c0578063c7977be711610074578063ea3c1aac11610059578063ea3c1aac146103fc578063eb3b39631461041c578063f20626241461043c5761014f565b8063c7977be7146103a8578063e7dd3117146103dc5761014f565b806395118154116100a5578063951181541461035b578063ae5c90ef146102e7578063aff8d6bf146103885761014f565b806390ef12cd1461030757806392fce5cb146103275761014f565b806347ac8cb41161011757806360b27e11116100fc57806360b27e111461028357806388f1f966146102c75780638bfc23c2146102e75761014f565b806347ac8cb4146102435780635831122a146102635761014f565b80631626ba7e1461017d5780631edd0d5b146101bb57806322ed94a0146101eb578063388be806146102235761014f565b3661014f57005b60003560e01c63bc197c81811463f23a6e6182141763150b7a028214171561017b57806020526020603cf35b005b34801561018957600080fd5b5061019d610198366004613a0a565b61045c565b6040516001600160e01b031990911681526020015b60405180910390f35b3480156101c757600080fd5b506101db6101d6366004613a51565b610498565b60405190151581526020016101b2565b3480156101f757600080fd5b5060025461020b906001600160a01b031681565b6040516001600160a01b0390911681526020016101b2565b34801561022f57600080fd5b506101db61023e366004613b46565b61071b565b34801561024f57600080fd5b5061020b61025e366004613bbe565b6107da565b34801561026f57600080fd5b5061017b61027e366004613cb4565b6109a4565b34801561028f57600080fd5b506102b961029e366004613d81565b6001600160a01b031660009081526005602052604090205490565b6040519081526020016101b2565b3480156102d357600080fd5b506102b96102e2366004613da5565b6112af565b3480156102f357600080fd5b506102b9610302366004613e37565b6117e7565b34801561031357600080fd5b5060015461020b906001600160a01b031681565b34801561033357600080fd5b506102b97ffcaab6a7d27a0e15a8d2fff8c95aedfb943871e8a02eeb319ef1018cab5e6bdc81565b34801561036757600080fd5b5061037b610376366004613a51565b611868565b6040516101b29190613f8d565b34801561039457600080fd5b5061017b6103a336600461407b565b611b1b565b3480156103b457600080fd5b506102b97f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b3480156103e857600080fd5b506101db6103f7366004613a51565b612094565b34801561040857600080fd5b5061017b610417366004613d81565b61273b565b34801561042857600080fd5b5061017b61043736600461409d565b6127d4565b34801561044857600080fd5b506102b96104573660046140cb565b612cdb565b6000600260008481526003602052604090205460ff16600481111561048357610483613e74565b036104925750630b135d3f60e11b5b92915050565b6002546000906001600160a01b031633146104c6576040516366e928db60e11b815260040160405180910390fd5b60006104d183612d66565b90506002815160048111156104e8576104e8613e74565b146105065760405163a29b1f1160e01b815260040160405180910390fd5b428160200151608001511161052e5760405163c26b3e3760e01b815260040160405180910390fd5b60208181015160038084526000868152925260409091208251815484929190829060ff1916600183600481111561056757610567613e74565b02179055506020820151805160018084018054909291839160ff19169083600281111561059657610596613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c0820151600582019061060d9082614214565b5050506040820151805161062b916007840191602090910190613751565b50606082015180516106479160088401916020909101906137b6565b50608082015181600901559050508160200151604001516001600160a01b03168160c0015160405161067991906142d4565b6000604051808303816000865af19150503d80600081146106b6576040519150601f19603f3d011682016040523d82523d6000602084013e6106bb565b606091505b505080935050826106df57604051632dc81b9960e11b815260040160405180910390fd5b6020820151606001516040518591907f6c4de46d19e4638328e46b03c9b3923038616459da4704969a4f050b4ea0aea590600090a35050919050565b60008060005461072a886117e7565b60405161190160f01b60208201526022810192909252604282015260620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156107b3573d6000803e3d6000fd5b5050604051601f1901516001600160a01b0390811690861614935050505095945050505050565b6002546000906001600160a01b0316331480159061080157506001600160a01b0382163014155b1561081f576040516366e928db60e11b815260040160405180910390fd5b6002546040516385752d0360e01b81526001600160a01b03868116600483015260248201869052909116906385752d0390604401602060405180830381865afa158015610870573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089491906142f0565b1580156108aa57506001600160a01b0382163014155b156108c8576040516359c5ba6f60e11b815260040160405180910390fd5b600660006108df6001600160a01b03851686614328565b815260208101919091526040016000205460ff161561091157604051633844cea560e01b815260040160405180910390fd5b60016006600061092a6001600160a01b03861687614328565b81526020810191909152604001600020805460ff1916911515919091179055610955848460036132a5565b604080516001600160a01b0380841682528516602082015291925084917f0b35ef51d96fda6f915671e15c3f4f00aed3c1412daf15a1b3941a503fb3fa69910160405180910390a29392505050565b6002546001600160a01b031633146109cf576040516366e928db60e11b815260040160405180910390fd5b600083815260036020526040808220815160a081019092528054829060ff1660048111156109ff576109ff613e74565b6004811115610a1057610a10613e74565b81526040805160e08101909152600183018054602090930192829060ff166002811115610a3f57610a3f613e74565b6002811115610a5057610a50613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c090920191610aa790614189565b80601f0160208091040260200160405190810160405280929190818152602001828054610ad390614189565b8015610b205780601f10610af557610100808354040283529160200191610b20565b820191906000526020600020905b815481529060010190602001808311610b0357829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015610b8657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b68575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015610c60578382906000526020600020018054610bd390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054610bff90614189565b8015610c4c5780601f10610c2157610100808354040283529160200191610c4c565b820191906000526020600020905b815481529060010190602001808311610c2f57829003601f168201915b505050505081526020019060010190610bb4565b505050508152602001600982015481525050905080606001515182511015610c9b576040516334f8d9d160e01b815260040160405180910390fd5b81518351610ca9919061433b565b600003610cc95760405163dcdd869160e01b815260040160405180910390fd5b8151835114610ceb576040516302be566360e01b815260040160405180910390fd5b6000610cfa82602001516117e7565b6000805460405161190160f01b60208201526022810191909152604281018390529192509060620160408051601f19818403018152919052805160209091012090506000805b8651811015610fd75760006001600160a01b0316878281518110610d6657610d66614352565b60200260200101516001600160a01b031603610d9557604051634dd74a5960e01b815260040160405180910390fd5b60066000888381518110610dab57610dab614352565b60200260200101516001600160a01b03168a60001c610dca9190614368565b815260208101919091526040016000205460ff16610fcf5760025487516001600160a01b03909116906385752d0390899084908110610e0b57610e0b614352565b60200260200101518760200151606001516040518363ffffffff1660e01b8152600401610e4d9291906001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015610e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8e91906142f0565b15610fcf576000806000610eba898581518110610ead57610ead614352565b60200260200101516133a9565b925092509250600060018785858560405160008152602001604052604051610efe949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610f20573d6000803e3d6000fd5b5050506020604051035190508a8581518110610f3e57610f3e614352565b60200260200101516001600160a01b0316816001600160a01b031614610f675750505050610fcf565b6001600660008d8881518110610f7f57610f7f614352565b60200260200101516001600160a01b03168f60001c610f9e9190614368565b81526020810191909152604001600020805460ff191691151591909117905585610fc78161437b565b965050505050505b600101610d40565b50801561127b57600081856040015151610ff19190614328565b905060008167ffffffffffffffff81111561100e5761100e613907565b604051908082528060200260200182016040528015611037578160200160208202803683370190505b50905060008267ffffffffffffffff81111561105557611055613907565b60405190808252806020026020018201604052801561108857816020015b60608152602001906001900390816110735790505b50905060005b87604001515181101561112e57876040015181815181106110b1576110b1614352565b60200260200101518382815181106110cb576110cb614352565b60200260200101906001600160a01b031690816001600160a01b0316815250508760600151818151811061110157611101614352565b602002602001015182828151811061111b5761111b614352565b602090810291909101015260010161108e565b5060408701515160005b8a5181101561122957600660008c838151811061115757611157614352565b60200260200101516001600160a01b03168e60001c6111769190614368565b815260208101919091526040016000205460ff1615611221578a81815181106111a1576111a1614352565b60200260200101518483815181106111bb576111bb614352565b60200260200101906001600160a01b031690816001600160a01b0316815250508981815181106111ed576111ed614352565b602002602001015183838151811061120757611207614352565b6020026020010181905250818061121d9061437b565b9250505b600101611138565b5060008b8152600360209081526040909120845161124f92600790920191860190613751565b5060008b81526003602090815260409091208351611275926008909201918501906137b6565b50505050505b60405187907f8387ab4c637f3db41524b211dabc557a37c55b59a6f9ae117dfdc610f590fcd090600090a250505050505050565b6002546000906001600160a01b031633146112dd576040516366e928db60e11b815260040160405180910390fd5b60028760ff1611806112f0575060ff8716155b1561130e5760405163074eb30760e01b815260040160405180910390fd5b6002546040516385752d0360e01b81526001600160a01b038a8116600483015260248201899052909116906385752d0390604401602060405180830381865afa15801561135f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138391906142f0565b6113a0576040516359c5ba6f60e11b815260040160405180910390fd5b846113ae8760ff8a1661433b565b6113b8919061433b565b6000036113d857604051631512b5fb60e31b815260040160405180910390fd5b60008390036113fa576040516375547cfb60e11b815260040160405180910390fd5b6001600160a01b038416611435576114138887896132a5565b6001600160a01b03811660009081526005602052604090208790559350611574565b6001600160a01b038416600090815260056020526040902054861461146d5760405163b311ec0360e01b815260040160405180910390fd5b306001600160a01b0316846001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d99190614394565b6001600160a01b031614158061155657508660ff16846001600160a01b03166334e0bebe6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561152c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155091906143b1565b60ff1614155b1561157457604051632bd888b960e21b815260040160405180910390fd5b6040805160e081018252600080825260808201523360208201526060810188905260a0810185905260c081018490526001600160a01b03861691810191909152426115c2876201518061433b565b6115cc9190614328565b6080820152600160ff8916146115e35760026115e6565b60015b819060028111156115f9576115f9613e74565b9081600281111561160c5761160c613e74565b905250611618816117e7565b6000888152600460209081526040822080546001810182559083529120018190559150611643613808565b60018152602080820183905260008481526003909152604081205460ff16600481111561167257611672613e74565b1461168f5760405162dc149f60e41b815260040160405180910390fd5b60008381526003602052604090208151815483929190829060ff191660018360048111156116bf576116bf613e74565b02179055506020820151805160018084018054909291839160ff1916908360028111156116ee576116ee613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906117659082614214565b50505060408201518051611783916007840191602090910190613751565b506060820151805161179f9160088401916020909101906137b6565b5060809190910151600990910155604051889084907f9c2020804817db931ea18693c6fc487ae1cb81b49567ffec2006e5cc4a0b797890600090a35050979650505050505050565b60007ffcaab6a7d27a0e15a8d2fff8c95aedfb943871e8a02eeb319ef1018cab5e6bdc826000015183602001518460400151856060015186608001518760a001518860c001518051906020012060405160200161184b9897969594939291906143ce565b604051602081830303815290604052805190602001209050919050565b611870613808565b60008281526003602052604090819020815160a081019092528054829060ff1660048111156118a1576118a1613e74565b60048111156118b2576118b2613e74565b81526040805160e08101909152600183018054602090930192829060ff1660028111156118e1576118e1613e74565b60028111156118f2576118f2613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c09092019161194990614189565b80601f016020809104026020016040519081016040528092919081815260200182805461197590614189565b80156119c25780601f10611997576101008083540402835291602001916119c2565b820191906000526020600020905b8154815290600101906020018083116119a557829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015611a2857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a0a575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015611b02578382906000526020600020018054611a7590614189565b80601f0160208091040260200160405190810160405280929190818152602001828054611aa190614189565b8015611aee5780601f10611ac357610100808354040283529160200191611aee565b820191906000526020600020905b815481529060010190602001808311611ad157829003601f168201915b505050505081526020019060010190611a56565b5050505081526020016009820154815250509050919050565b600082815260036020526040808220815160a081019092528054829060ff166004811115611b4b57611b4b613e74565b6004811115611b5c57611b5c613e74565b81526040805160e08101909152600183018054602090930192829060ff166002811115611b8b57611b8b613e74565b6002811115611b9c57611b9c613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c090920191611bf390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054611c1f90614189565b8015611c6c5780601f10611c4157610100808354040283529160200191611c6c565b820191906000526020600020905b815481529060010190602001808311611c4f57829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015611cd257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611cb4575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015611dac578382906000526020600020018054611d1f90614189565b80601f0160208091040260200160405190810160405280929190818152602001828054611d4b90614189565b8015611d985780601f10611d6d57610100808354040283529160200191611d98565b820191906000526020600020905b815481529060010190602001808311611d7b57829003601f168201915b505050505081526020019060010190611d00565b5050505081526020016009820154815250509050428160200151608001511115611dd557600481525b600181516004811115611dea57611dea613e74565b1480611e085750600281516004811115611e0657611e06613e74565b145b15611e265760405163e4fb146b60e01b815260040160405180910390fd5b826004600083602001516060015181526020019081526020016000208381548110611e5357611e53614352565b906000526020600020015414611e7c5760405163b4e2e10d60e01b815260040160405180910390fd5b6004600082602001516060015181526020019081526020016000208281548110611ea857611ea8614352565b906000526020600020016000905581600460008360200151606001518152602001908152602001600020600081548110611ee457611ee4614352565b906000526020600020015460001c1115611f2e576020808201516060015160009081526004909152604081208054849290611f2157611f21614352565b6000918252602090912001555b60008381526003602052604090208151815483929190829060ff19166001836004811115611f5e57611f5e613e74565b02179055506020820151805160018084018054909291839160ff191690836002811115611f8d57611f8d613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906120049082614214565b50505060408201518051612022916007840191602090910190613751565b506060820151805161203e9160088401916020909101906137b6565b5060808201518160090155905050828160200151606001517f19d228802ce661480d557248c8f4215fdb3ed19e0b49df06ae0672ca23948c088460405161208791815260200190565b60405180910390a3505050565b600081815260036020526040808220815160a08101909252805483929190829060ff1660048111156120c8576120c8613e74565b60048111156120d9576120d9613e74565b81526040805160e08101909152600183018054602090930192829060ff16600281111561210857612108613e74565b600281111561211957612119613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c09092019161217090614189565b80601f016020809104026020016040519081016040528092919081815260200182805461219c90614189565b80156121e95780601f106121be576101008083540402835291602001916121e9565b820191906000526020600020905b8154815290600101906020018083116121cc57829003601f168201915b50505050508152505081526020016007820180548060200260200160405190810160405280929190818152602001828054801561224f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612231575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b8282101561232957838290600052602060002001805461229c90614189565b80601f01602080910402602001604051908101604052809291908181526020018280546122c890614189565b80156123155780601f106122ea57610100808354040283529160200191612315565b820191906000526020600020905b8154815290600101906020018083116122f857829003601f168201915b50505050508152602001906001019061227d565b505050908252506009919091015460209091015290506000602082015151600281111561235857612358613e74565b036123665750600092915050565b60028151600481111561237b5761237b613e74565b036123895750600192915050565b60048151600481111561239e5761239e613e74565b036123ac5750600092915050565b6001815160048111156123c1576123c1613e74565b146123cf5750600092915050565b8060400151516000036123e55750600092915050565b806060015151816040015151146123ff5750600092915050565b604080820151606083015160008054935161190160f01b6020820152602281019490945260428401879052928392919083906062016040516020818303038152906040528051906020012090505b81518510156125ca5760006001600160a01b031683868151811061247357612473614352565b60200260200101516001600160a01b031603156125bf576124c783868151811061249f5761249f614352565b6020026020010151828488815181106124ba576124ba614352565b602002602001015161349a565b6124d957506000979650505050505050565b600260208701515160028111156124f2576124f2613e74565b1461250757612502846001614328565b6125bc565b60025483516001600160a01b039091169062fdd58e9085908890811061252f5761252f614352565b60200260200101518860200151606001516040518363ffffffff1660e01b81526004016125719291906001600160a01b03929092168252602082015260400190565b602060405180830381865afa15801561258e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b29190614420565b6125bc9085614328565b93505b84600101945061244d565b831561272d57600260208701515160028111156125e9576125e9613e74565b03612683576002805460208801516060015160405163bd85b03960e01b81526001600160a01b039092169163bd85b0399161262a9160040190815260200190565b602060405180830381865afa158015612647573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266b9190614420565b6126759190614439565b909311979650505050505050565b6001602087015151600281111561269c5761269c613e74565b0361272d576002805460208801516060015160405163eef2e75760e01b81526001600160a01b039092169163eef2e757916126dd9160040190815260200190565b600060405180830381865afa1580156126fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612722919081019061445b565b516126759190614439565b506000979650505050505050565b6002546001600160a01b031661276757600280546001600160a01b0319166001600160a01b0383161790555b6001546001600160a01b0316330361279557600280546001600160a01b0319166001600160a01b0383161790555b6040516001600160a01b03821681527f68e0e5615e0f0beac903df596e5f37d76055e23925dde4e747a159ed0170424f9060200160405180910390a150565b6002546001600160a01b031633146127ff576040516366e928db60e11b815260040160405180910390fd5b600083815260036020526040808220815160a081019092528054829060ff16600481111561282f5761282f613e74565b600481111561284057612840613e74565b81526040805160e08101909152600183018054602090930192829060ff16600281111561286f5761286f613e74565b600281111561288057612880613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c0909201916128d790614189565b80601f016020809104026020016040519081016040528092919081815260200182805461290390614189565b80156129505780601f1061292557610100808354040283529160200191612950565b820191906000526020600020905b81548152906001019060200180831161293357829003601f168201915b5050505050815250508152602001600782018054806020026020016040519081016040528092919081815260200182805480156129b657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612998575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015612a90578382906000526020600020018054612a0390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054612a2f90614189565b8015612a7c5780601f10612a5157610100808354040283529160200191612a7c565b820191906000526020600020905b815481529060010190602001808311612a5f57829003601f168201915b5050505050815260200190600101906129e4565b5050505081526020016009820154815250509050816001600160a01b031681604001518481518110612ac457612ac4614352565b60200260200101516001600160a01b031614612af35760405163490be95360e11b815260040160405180910390fd5b80606001518381518110612b0957612b09614352565b60200260200101606081525080604001518381518110612b2b57612b2b614352565b6000602091820292909201810182905285825260039052604090208151815483929190829060ff19166001836004811115612b6857612b68613e74565b02179055506020820151805160018084018054909291839160ff191690836002811115612b9757612b97613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c08201516005820190612c0e9082614214565b50505060408201518051612c2c916007840191602090910190613751565b5060608201518051612c489160088401916020909101906137b6565b50608091909101516009909101556000600681612c6e6001600160a01b03861688614368565b81526020808201929092526040908101600020805460ff191693151593909317909255828101516060015191516001600160a01b03851681528692917f72e8bb41de86f6a048361bf7dda6aee93fedcc6e8ac99520b47e6f289eb449d8910160405180910390a350505050565b60007fd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac5647282600001518051906020012083602001518051906020012084604001518560600151866080015160405160200161184b969594939291909586526020860194909452604085019290925260608401526001600160a01b0316608083015260a082015260c00190565b612d6e613808565b60008281526003602052604090819020815160a081019092528054829060ff166004811115612d9f57612d9f613e74565b6004811115612db057612db0613e74565b81526040805160e08101909152600183018054602090930192829060ff166002811115612ddf57612ddf613e74565b6002811115612df057612df0613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c090920191612e4790614189565b80601f0160208091040260200160405190810160405280929190818152602001828054612e7390614189565b8015612ec05780601f10612e9557610100808354040283529160200191612ec0565b820191906000526020600020905b815481529060010190602001808311612ea357829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015612f2657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f08575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015613000578382906000526020600020018054612f7390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9f90614189565b8015612fec5780601f10612fc157610100808354040283529160200191612fec565b820191906000526020600020905b815481529060010190602001808311612fcf57829003601f168201915b505050505081526020019060010190612f54565b505050508152602001600982015481525050905042816020015160800151116131465760048082526000838152600360205260409020825181548493839160ff191690600190849081111561305757613057613e74565b02179055506020820151805160018084018054909291839160ff19169083600281111561308657613086613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906130fd9082614214565b5050506040820151805161311b916007840191602090910190613751565b50606082015180516131379160088401916020909101906137b6565b50608082015181600901559050505b600061315582602001516117e7565b905061316081612094565b61317d57604051631150cdbd60e11b815260040160405180910390fd5b6002825260008381526003602052604090208251815484929190829060ff191660018360048111156131b1576131b1613e74565b02179055506020820151805160018084018054909291839160ff1916908360028111156131e0576131e0613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906132579082614214565b50505060408201518051613275916007840191602090910190613751565b50606082015180516132919160088401916020909101906137b6565b506080820151816009015590505050919050565b6000632e14dcd360e21b81356001600160e01b0319160161330c576132cb8460036134fb565b90506001600160a01b03841630146132ec57836001600160a01b03166132ee565b825b6001600160a01b038216600090815260056020526040902055613334565b61331630836134fb565b6001600160a01b038116600090815260056020526040902084905590505b600254604051631465471360e11b81526001600160a01b038381166004830152602482018690528681166044830152909116906328ca8e2690606401600060405180830381600087803b15801561338a57600080fd5b505af115801561339e573d6000803e3d6000fd5b505050509392505050565b600080600083516041146134045760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e677468000000000000000060448201526064015b60405180910390fd5b50505060208101516040820151606083015160001a9190601b8310156134325761342f601b846144f5565b92505b8260ff16601b148061344757508260ff16601c145b6134935760405162461bcd60e51b815260206004820152601b60248201527f496e76616c6964207369676e6174757265202776272076616c7565000000000060448201526064016133fb565b9193909250565b60008060006134a98585613547565b909250905060008160048111156134c2576134c2613e74565b1480156134e05750856001600160a01b0316826001600160a01b0316145b806134f157506134f186868661358c565b9695505050505050565b6000828260405161350b9061388b565b6001600160a01b03909216825260ff166020820152604001604051809103906000f08015801561353f573d6000803e3d6000fd5b509392505050565b600080825160410361357d5760208301516040840151606085015160001a6135718782858561368d565b94509450505050613585565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b86866040516024016135b692919061450e565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990941693909317909252905161360991906142d4565b600060405180830381855afa9150503d8060008114613644576040519150601f19603f3d011682016040523d82523d6000602084013e613649565b606091505b509150915081801561365d57506020815110155b80156134f157508051630b135d3f60e11b906136829083016020908101908401614420565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156136c45750600090506003613748565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613718573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661374157600060019250925050613748565b9150600090505b94509492505050565b8280548282559060005260206000209081019282156137a6579160200282015b828111156137a657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613771565b506137b2929150613898565b5090565b8280548282559060005260206000209081019282156137fc579160200282015b828111156137fc57825182906137ec9082614214565b50916020019190600101906137d6565b506137b29291506138ad565b6040805160a0810190915280600081526020016138716040805160e08101909152806000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008019168152602001606081525090565b815260606020820181905260408201819052600091015290565b610a028061452883390190565b5b808211156137b25760008155600101613899565b808211156137b25760006138c182826138ca565b506001016138ad565b5080546138d690614189565b6000825580601f106138e6575050565b601f0160209004906000526020600020908101906139049190613898565b50565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561394057613940613907565b60405290565b60405160a0810167ffffffffffffffff8111828210171561394057613940613907565b604051601f8201601f1916810167ffffffffffffffff8111828210171561399257613992613907565b604052919050565b600082601f8301126139ab57600080fd5b813567ffffffffffffffff8111156139c5576139c5613907565b6139d8601f8201601f1916602001613969565b8181528460208386010111156139ed57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613a1d57600080fd5b82359150602083013567ffffffffffffffff811115613a3b57600080fd5b613a478582860161399a565b9150509250929050565b600060208284031215613a6357600080fd5b5035919050565b803560038110613a7957600080fd5b919050565b6001600160a01b038116811461390457600080fd5b8035613a7981613a7e565b600060e08284031215613ab057600080fd5b613ab861391d565b9050613ac382613a6a565b8152613ad160208301613a93565b6020820152613ae260408301613a93565b6040820152606082013560608201526080820135608082015260a082013560a082015260c082013567ffffffffffffffff811115613b1f57600080fd5b613b2b8482850161399a565b60c08301525092915050565b60ff8116811461390457600080fd5b600080600080600060a08688031215613b5e57600080fd5b853567ffffffffffffffff811115613b7557600080fd5b613b8188828901613a9e565b9550506020860135613b9281613b37565b935060408601359250606086013591506080860135613bb081613a7e565b809150509295509295909350565b600080600060608486031215613bd357600080fd5b8335613bde81613a7e565b9250602084013591506040840135613bf581613a7e565b809150509250925092565b600067ffffffffffffffff821115613c1a57613c1a613907565b5060051b60200190565b600082601f830112613c3557600080fd5b81356020613c4a613c4583613c00565b613969565b82815260059290921b84018101918181019086841115613c6957600080fd5b8286015b84811015613ca957803567ffffffffffffffff811115613c8d5760008081fd5b613c9b8986838b010161399a565b845250918301918301613c6d565b509695505050505050565b600080600060608486031215613cc957600080fd5b8335925060208085013567ffffffffffffffff80821115613ce957600080fd5b818701915087601f830112613cfd57600080fd5b8135613d0b613c4582613c00565b81815260059190911b8301840190848101908a831115613d2a57600080fd5b938501935b82851015613d51578435613d4281613a7e565b82529385019390850190613d2f565b965050506040870135925080831115613d6957600080fd5b5050613d7786828701613c24565b9150509250925092565b600060208284031215613d9357600080fd5b8135613d9e81613a7e565b9392505050565b600080600080600080600060e0888a031215613dc057600080fd5b8735613dcb81613a7e565b96506020880135613ddb81613b37565b955060408801359450606088013593506080880135613df981613a7e565b925060a0880135915060c088013567ffffffffffffffff811115613e1c57600080fd5b613e288a828b0161399a565b91505092959891949750929550565b600060208284031215613e4957600080fd5b813567ffffffffffffffff811115613e6057600080fd5b613e6c84828501613a9e565b949350505050565b634e487b7160e01b600052602160045260246000fd5b60038110613e9a57613e9a613e74565b9052565b60005b83811015613eb9578181015183820152602001613ea1565b50506000910152565b60008151808452613eda816020860160208601613e9e565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b83811015613f285781516001600160a01b031687529582019590820190600101613f03565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015613f8057601f19868403018952613f6e838351613ec2565b98840198925090830190600101613f52565b5090979650505050505050565b602081526000825160058110613fa557613fa5613e74565b80602084015250602083015160a06040840152613fc660c084018251613e8a565b60208101516001600160a01b0380821660e08601528060408401511661010086015250506060810151610120840152608081015161014084015260a081015161016084015260c0810151905060e06101808401526140286101a0840182613ec2565b90506040840151601f19808584030160608601526140468383613eee565b92506060860151915080858403016080860152506140648282613f33565b915050608084015160a08401528091505092915050565b6000806040838503121561408e57600080fd5b50508035926020909101359150565b6000806000606084860312156140b257600080fd5b83359250602084013591506040840135613bf581613a7e565b6000602082840312156140dd57600080fd5b813567ffffffffffffffff808211156140f557600080fd5b9083019060a0828603121561410957600080fd5b614111613946565b82358281111561412057600080fd5b61412c8782860161399a565b82525060208301358281111561414157600080fd5b61414d8782860161399a565b602083015250604083013560408201526060830135915061416d82613a7e565b8160608201526080830135608082015280935050505092915050565b600181811c9082168061419d57607f821691505b6020821081036141bd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561420f576000816000526020600020601f850160051c810160208610156141ec5750805b601f850160051c820191505b8181101561420b578281556001016141f8565b5050505b505050565b815167ffffffffffffffff81111561422e5761422e613907565b6142428161423c8454614189565b846141c3565b602080601f831160018114614277576000841561425f5750858301515b600019600386901b1c1916600185901b17855561420b565b600085815260208120601f198616915b828110156142a657888601518255948401946001909101908401614287565b50858210156142c45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082516142e6818460208701613e9e565b9190910192915050565b60006020828403121561430257600080fd5b81518015158114613d9e57600080fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561049257610492614312565b808202811582820484141761049257610492614312565b634e487b7160e01b600052603260045260246000fd5b8181038181111561049257610492614312565b60006001820161438d5761438d614312565b5060010190565b6000602082840312156143a657600080fd5b8151613d9e81613a7e565b6000602082840312156143c357600080fd5b8151613d9e81613b37565b88815261010081016143e3602083018a613e8a565b6001600160a01b039788166040830152959096166060870152608086019390935260a085019190915260c084015260e09092019190915292915050565b60006020828403121561443257600080fd5b5051919050565b60008261445657634e487b7160e01b600052601260045260246000fd5b500490565b6000602080838503121561446e57600080fd5b825167ffffffffffffffff81111561448557600080fd5b8301601f8101851361449657600080fd5b80516144a4613c4582613c00565b81815260059190911b820183019083810190878311156144c357600080fd5b928401925b828410156144ea5783516144db81613a7e565b825292840192908401906144c8565b979650505050505050565b60ff818116838216019081111561049257610492614312565b828152604060208201526000613e6c6040830184613ec256fe60a0604052348015600f57600080fd5b50604051610a02380380610a02833981016040819052602c916057565b600080546001600160a01b0319166001600160a01b03939093169290921790915560ff1660805260a0565b60008060408385031215606957600080fd5b82516001600160a01b0381168114607f57600080fd5b602084015190925060ff81168114609557600080fd5b809150509250929050565b6080516109476100bb60003960006101a801526109476000f3fe60806040526004361061009a5760003560e01c80638da5cb5b11610069578063cb2f1df31161004e578063cb2f1df314610261578063d784d42614610281578063f23a6e61146102a1576100a1565b80638da5cb5b14610214578063bce38bd714610234576100a1565b806313af4035146101205780631626ba7e1461014057806334e0bebe146101965780635c60da1b146101dc576100a1565b366100a157005b60003560e01c63bc197c81811463f23a6e6182141763150b7a02821417156100cd57806020526020603cf35b506001546001600160a01b03166100f757604051631174132960e21b815260040160405180910390fd5b6001543660008037600080366000845af43d6000803e808015610119573d6000f35b3d6000fd5b005b34801561012c57600080fd5b5061011e61013b3660046105f2565b6102ce565b34801561014c57600080fd5b5061016061015b366004610656565b610328565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b3480156101a257600080fd5b506101ca7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161018d565b3480156101e857600080fd5b506001546101fc906001600160a01b031681565b6040516001600160a01b03909116815260200161018d565b34801561022057600080fd5b506000546101fc906001600160a01b031681565b34801561024057600080fd5b5061025461024f3660046106a2565b610350565b60405161018d919061072f565b34801561026d57600080fd5b5061011e61027c3660046107dd565b61051f565b34801561028d57600080fd5b5061011e61029c3660046105f2565b61056a565b3480156102ad57600080fd5b506101606102bc3660046107f6565b63f23a6e6160e01b9695505050505050565b6000546001600160a01b031633146102f9576040516330cd747160e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60008381526002602052604081205460ff16156103495750630b135d3f60e11b5b9392505050565b6000546060906001600160a01b0316331461037e576040516330cd747160e01b815260040160405180910390fd5b8167ffffffffffffffff8111156103975761039761086e565b6040519080825280602002602001820160405280156103dd57816020015b6040805180820190915260008152606060208201528152602001906001900390816103b55790505b50905060005b828110156105175760008085858481811061040057610400610884565b9050602002810190610412919061089a565b6104209060208101906105f2565b6001600160a01b031686868581811061043b5761043b610884565b905060200281019061044d919061089a565b61045b9060208101906108ba565b604051610469929190610901565b6000604051808303816000865af19150503d80600081146104a6576040519150601f19603f3d011682016040523d82523d6000602084013e6104ab565b606091505b50915091508680156104bb575081155b156104d95760405163177a8f7f60e11b815260040160405180910390fd5b604051806040016040528083151581526020018281525084848151811061050257610502610884565b602090810291909101015250506001016103e3565b509392505050565b6000546001600160a01b0316331461054a576040516330cd747160e01b815260040160405180910390fd5b6000908152600260205260409020805460ff19811660ff90911615179055565b6000546001600160a01b03163314610595576040516330cd747160e01b815260040160405180910390fd5b6001546001600160a01b038281169116146105d3576001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383161790555b50565b80356001600160a01b03811681146105ed57600080fd5b919050565b60006020828403121561060457600080fd5b610349826105d6565b60008083601f84011261061f57600080fd5b50813567ffffffffffffffff81111561063757600080fd5b60208301915083602082850101111561064f57600080fd5b9250929050565b60008060006040848603121561066b57600080fd5b83359250602084013567ffffffffffffffff81111561068957600080fd5b6106958682870161060d565b9497909650939450505050565b6000806000604084860312156106b757600080fd5b833580151581146106c757600080fd5b9250602084013567ffffffffffffffff808211156106e457600080fd5b818601915086601f8301126106f857600080fd5b81358181111561070757600080fd5b8760208260051b850101111561071c57600080fd5b6020830194508093505050509250925092565b600060208083018184528085518083526040925060408601915060408160051b8701018488016000805b848110156107ce57898403603f1901865282518051151585528801518885018890528051888601819052835b818110156107a1578281018b0151878201606001528a01610785565b508581016060908101859052978a0197601f909101601f1916909501909401935091870191600101610759565b50919998505050505050505050565b6000602082840312156107ef57600080fd5b5035919050565b60008060008060008060a0878903121561080f57600080fd5b610818876105d6565b9550610826602088016105d6565b94506040870135935060608701359250608087013567ffffffffffffffff81111561085057600080fd5b61085c89828a0161060d565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235603e198336030181126108b057600080fd5b9190910192915050565b6000808335601e198436030181126108d157600080fd5b83018035915067ffffffffffffffff8211156108ec57600080fd5b60200191503681900382131561064f57600080fd5b818382376000910190815291905056fea2646970667358221220395efa67fb5c0c6ef2a85441ecb434b818f7b9186748556c0621251a1adbaf6a64736f6c63430008190033a264697066735822122006cd09e264550c4cd1d7c5125a4882591338e64fbf26f9e6001b8d95cbdb306e64736f6c6343000819003300000000000000000000000082cb12995f4861d317a6c7c72917be3c243222a6
Deployed ByteCode
0x6080604052600436106101485760003560e01c806390ef12cd116100c0578063c7977be711610074578063ea3c1aac11610059578063ea3c1aac146103fc578063eb3b39631461041c578063f20626241461043c5761014f565b8063c7977be7146103a8578063e7dd3117146103dc5761014f565b806395118154116100a5578063951181541461035b578063ae5c90ef146102e7578063aff8d6bf146103885761014f565b806390ef12cd1461030757806392fce5cb146103275761014f565b806347ac8cb41161011757806360b27e11116100fc57806360b27e111461028357806388f1f966146102c75780638bfc23c2146102e75761014f565b806347ac8cb4146102435780635831122a146102635761014f565b80631626ba7e1461017d5780631edd0d5b146101bb57806322ed94a0146101eb578063388be806146102235761014f565b3661014f57005b60003560e01c63bc197c81811463f23a6e6182141763150b7a028214171561017b57806020526020603cf35b005b34801561018957600080fd5b5061019d610198366004613a0a565b61045c565b6040516001600160e01b031990911681526020015b60405180910390f35b3480156101c757600080fd5b506101db6101d6366004613a51565b610498565b60405190151581526020016101b2565b3480156101f757600080fd5b5060025461020b906001600160a01b031681565b6040516001600160a01b0390911681526020016101b2565b34801561022f57600080fd5b506101db61023e366004613b46565b61071b565b34801561024f57600080fd5b5061020b61025e366004613bbe565b6107da565b34801561026f57600080fd5b5061017b61027e366004613cb4565b6109a4565b34801561028f57600080fd5b506102b961029e366004613d81565b6001600160a01b031660009081526005602052604090205490565b6040519081526020016101b2565b3480156102d357600080fd5b506102b96102e2366004613da5565b6112af565b3480156102f357600080fd5b506102b9610302366004613e37565b6117e7565b34801561031357600080fd5b5060015461020b906001600160a01b031681565b34801561033357600080fd5b506102b97ffcaab6a7d27a0e15a8d2fff8c95aedfb943871e8a02eeb319ef1018cab5e6bdc81565b34801561036757600080fd5b5061037b610376366004613a51565b611868565b6040516101b29190613f8d565b34801561039457600080fd5b5061017b6103a336600461407b565b611b1b565b3480156103b457600080fd5b506102b97f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b3480156103e857600080fd5b506101db6103f7366004613a51565b612094565b34801561040857600080fd5b5061017b610417366004613d81565b61273b565b34801561042857600080fd5b5061017b61043736600461409d565b6127d4565b34801561044857600080fd5b506102b96104573660046140cb565b612cdb565b6000600260008481526003602052604090205460ff16600481111561048357610483613e74565b036104925750630b135d3f60e11b5b92915050565b6002546000906001600160a01b031633146104c6576040516366e928db60e11b815260040160405180910390fd5b60006104d183612d66565b90506002815160048111156104e8576104e8613e74565b146105065760405163a29b1f1160e01b815260040160405180910390fd5b428160200151608001511161052e5760405163c26b3e3760e01b815260040160405180910390fd5b60208181015160038084526000868152925260409091208251815484929190829060ff1916600183600481111561056757610567613e74565b02179055506020820151805160018084018054909291839160ff19169083600281111561059657610596613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c0820151600582019061060d9082614214565b5050506040820151805161062b916007840191602090910190613751565b50606082015180516106479160088401916020909101906137b6565b50608082015181600901559050508160200151604001516001600160a01b03168160c0015160405161067991906142d4565b6000604051808303816000865af19150503d80600081146106b6576040519150601f19603f3d011682016040523d82523d6000602084013e6106bb565b606091505b505080935050826106df57604051632dc81b9960e11b815260040160405180910390fd5b6020820151606001516040518591907f6c4de46d19e4638328e46b03c9b3923038616459da4704969a4f050b4ea0aea590600090a35050919050565b60008060005461072a886117e7565b60405161190160f01b60208201526022810192909252604282015260620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156107b3573d6000803e3d6000fd5b5050604051601f1901516001600160a01b0390811690861614935050505095945050505050565b6002546000906001600160a01b0316331480159061080157506001600160a01b0382163014155b1561081f576040516366e928db60e11b815260040160405180910390fd5b6002546040516385752d0360e01b81526001600160a01b03868116600483015260248201869052909116906385752d0390604401602060405180830381865afa158015610870573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089491906142f0565b1580156108aa57506001600160a01b0382163014155b156108c8576040516359c5ba6f60e11b815260040160405180910390fd5b600660006108df6001600160a01b03851686614328565b815260208101919091526040016000205460ff161561091157604051633844cea560e01b815260040160405180910390fd5b60016006600061092a6001600160a01b03861687614328565b81526020810191909152604001600020805460ff1916911515919091179055610955848460036132a5565b604080516001600160a01b0380841682528516602082015291925084917f0b35ef51d96fda6f915671e15c3f4f00aed3c1412daf15a1b3941a503fb3fa69910160405180910390a29392505050565b6002546001600160a01b031633146109cf576040516366e928db60e11b815260040160405180910390fd5b600083815260036020526040808220815160a081019092528054829060ff1660048111156109ff576109ff613e74565b6004811115610a1057610a10613e74565b81526040805160e08101909152600183018054602090930192829060ff166002811115610a3f57610a3f613e74565b6002811115610a5057610a50613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c090920191610aa790614189565b80601f0160208091040260200160405190810160405280929190818152602001828054610ad390614189565b8015610b205780601f10610af557610100808354040283529160200191610b20565b820191906000526020600020905b815481529060010190602001808311610b0357829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015610b8657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b68575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015610c60578382906000526020600020018054610bd390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054610bff90614189565b8015610c4c5780601f10610c2157610100808354040283529160200191610c4c565b820191906000526020600020905b815481529060010190602001808311610c2f57829003601f168201915b505050505081526020019060010190610bb4565b505050508152602001600982015481525050905080606001515182511015610c9b576040516334f8d9d160e01b815260040160405180910390fd5b81518351610ca9919061433b565b600003610cc95760405163dcdd869160e01b815260040160405180910390fd5b8151835114610ceb576040516302be566360e01b815260040160405180910390fd5b6000610cfa82602001516117e7565b6000805460405161190160f01b60208201526022810191909152604281018390529192509060620160408051601f19818403018152919052805160209091012090506000805b8651811015610fd75760006001600160a01b0316878281518110610d6657610d66614352565b60200260200101516001600160a01b031603610d9557604051634dd74a5960e01b815260040160405180910390fd5b60066000888381518110610dab57610dab614352565b60200260200101516001600160a01b03168a60001c610dca9190614368565b815260208101919091526040016000205460ff16610fcf5760025487516001600160a01b03909116906385752d0390899084908110610e0b57610e0b614352565b60200260200101518760200151606001516040518363ffffffff1660e01b8152600401610e4d9291906001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015610e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8e91906142f0565b15610fcf576000806000610eba898581518110610ead57610ead614352565b60200260200101516133a9565b925092509250600060018785858560405160008152602001604052604051610efe949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610f20573d6000803e3d6000fd5b5050506020604051035190508a8581518110610f3e57610f3e614352565b60200260200101516001600160a01b0316816001600160a01b031614610f675750505050610fcf565b6001600660008d8881518110610f7f57610f7f614352565b60200260200101516001600160a01b03168f60001c610f9e9190614368565b81526020810191909152604001600020805460ff191691151591909117905585610fc78161437b565b965050505050505b600101610d40565b50801561127b57600081856040015151610ff19190614328565b905060008167ffffffffffffffff81111561100e5761100e613907565b604051908082528060200260200182016040528015611037578160200160208202803683370190505b50905060008267ffffffffffffffff81111561105557611055613907565b60405190808252806020026020018201604052801561108857816020015b60608152602001906001900390816110735790505b50905060005b87604001515181101561112e57876040015181815181106110b1576110b1614352565b60200260200101518382815181106110cb576110cb614352565b60200260200101906001600160a01b031690816001600160a01b0316815250508760600151818151811061110157611101614352565b602002602001015182828151811061111b5761111b614352565b602090810291909101015260010161108e565b5060408701515160005b8a5181101561122957600660008c838151811061115757611157614352565b60200260200101516001600160a01b03168e60001c6111769190614368565b815260208101919091526040016000205460ff1615611221578a81815181106111a1576111a1614352565b60200260200101518483815181106111bb576111bb614352565b60200260200101906001600160a01b031690816001600160a01b0316815250508981815181106111ed576111ed614352565b602002602001015183838151811061120757611207614352565b6020026020010181905250818061121d9061437b565b9250505b600101611138565b5060008b8152600360209081526040909120845161124f92600790920191860190613751565b5060008b81526003602090815260409091208351611275926008909201918501906137b6565b50505050505b60405187907f8387ab4c637f3db41524b211dabc557a37c55b59a6f9ae117dfdc610f590fcd090600090a250505050505050565b6002546000906001600160a01b031633146112dd576040516366e928db60e11b815260040160405180910390fd5b60028760ff1611806112f0575060ff8716155b1561130e5760405163074eb30760e01b815260040160405180910390fd5b6002546040516385752d0360e01b81526001600160a01b038a8116600483015260248201899052909116906385752d0390604401602060405180830381865afa15801561135f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138391906142f0565b6113a0576040516359c5ba6f60e11b815260040160405180910390fd5b846113ae8760ff8a1661433b565b6113b8919061433b565b6000036113d857604051631512b5fb60e31b815260040160405180910390fd5b60008390036113fa576040516375547cfb60e11b815260040160405180910390fd5b6001600160a01b038416611435576114138887896132a5565b6001600160a01b03811660009081526005602052604090208790559350611574565b6001600160a01b038416600090815260056020526040902054861461146d5760405163b311ec0360e01b815260040160405180910390fd5b306001600160a01b0316846001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d99190614394565b6001600160a01b031614158061155657508660ff16846001600160a01b03166334e0bebe6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561152c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155091906143b1565b60ff1614155b1561157457604051632bd888b960e21b815260040160405180910390fd5b6040805160e081018252600080825260808201523360208201526060810188905260a0810185905260c081018490526001600160a01b03861691810191909152426115c2876201518061433b565b6115cc9190614328565b6080820152600160ff8916146115e35760026115e6565b60015b819060028111156115f9576115f9613e74565b9081600281111561160c5761160c613e74565b905250611618816117e7565b6000888152600460209081526040822080546001810182559083529120018190559150611643613808565b60018152602080820183905260008481526003909152604081205460ff16600481111561167257611672613e74565b1461168f5760405162dc149f60e41b815260040160405180910390fd5b60008381526003602052604090208151815483929190829060ff191660018360048111156116bf576116bf613e74565b02179055506020820151805160018084018054909291839160ff1916908360028111156116ee576116ee613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906117659082614214565b50505060408201518051611783916007840191602090910190613751565b506060820151805161179f9160088401916020909101906137b6565b5060809190910151600990910155604051889084907f9c2020804817db931ea18693c6fc487ae1cb81b49567ffec2006e5cc4a0b797890600090a35050979650505050505050565b60007ffcaab6a7d27a0e15a8d2fff8c95aedfb943871e8a02eeb319ef1018cab5e6bdc826000015183602001518460400151856060015186608001518760a001518860c001518051906020012060405160200161184b9897969594939291906143ce565b604051602081830303815290604052805190602001209050919050565b611870613808565b60008281526003602052604090819020815160a081019092528054829060ff1660048111156118a1576118a1613e74565b60048111156118b2576118b2613e74565b81526040805160e08101909152600183018054602090930192829060ff1660028111156118e1576118e1613e74565b60028111156118f2576118f2613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c09092019161194990614189565b80601f016020809104026020016040519081016040528092919081815260200182805461197590614189565b80156119c25780601f10611997576101008083540402835291602001916119c2565b820191906000526020600020905b8154815290600101906020018083116119a557829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015611a2857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a0a575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015611b02578382906000526020600020018054611a7590614189565b80601f0160208091040260200160405190810160405280929190818152602001828054611aa190614189565b8015611aee5780601f10611ac357610100808354040283529160200191611aee565b820191906000526020600020905b815481529060010190602001808311611ad157829003601f168201915b505050505081526020019060010190611a56565b5050505081526020016009820154815250509050919050565b600082815260036020526040808220815160a081019092528054829060ff166004811115611b4b57611b4b613e74565b6004811115611b5c57611b5c613e74565b81526040805160e08101909152600183018054602090930192829060ff166002811115611b8b57611b8b613e74565b6002811115611b9c57611b9c613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c090920191611bf390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054611c1f90614189565b8015611c6c5780601f10611c4157610100808354040283529160200191611c6c565b820191906000526020600020905b815481529060010190602001808311611c4f57829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015611cd257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611cb4575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015611dac578382906000526020600020018054611d1f90614189565b80601f0160208091040260200160405190810160405280929190818152602001828054611d4b90614189565b8015611d985780601f10611d6d57610100808354040283529160200191611d98565b820191906000526020600020905b815481529060010190602001808311611d7b57829003601f168201915b505050505081526020019060010190611d00565b5050505081526020016009820154815250509050428160200151608001511115611dd557600481525b600181516004811115611dea57611dea613e74565b1480611e085750600281516004811115611e0657611e06613e74565b145b15611e265760405163e4fb146b60e01b815260040160405180910390fd5b826004600083602001516060015181526020019081526020016000208381548110611e5357611e53614352565b906000526020600020015414611e7c5760405163b4e2e10d60e01b815260040160405180910390fd5b6004600082602001516060015181526020019081526020016000208281548110611ea857611ea8614352565b906000526020600020016000905581600460008360200151606001518152602001908152602001600020600081548110611ee457611ee4614352565b906000526020600020015460001c1115611f2e576020808201516060015160009081526004909152604081208054849290611f2157611f21614352565b6000918252602090912001555b60008381526003602052604090208151815483929190829060ff19166001836004811115611f5e57611f5e613e74565b02179055506020820151805160018084018054909291839160ff191690836002811115611f8d57611f8d613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906120049082614214565b50505060408201518051612022916007840191602090910190613751565b506060820151805161203e9160088401916020909101906137b6565b5060808201518160090155905050828160200151606001517f19d228802ce661480d557248c8f4215fdb3ed19e0b49df06ae0672ca23948c088460405161208791815260200190565b60405180910390a3505050565b600081815260036020526040808220815160a08101909252805483929190829060ff1660048111156120c8576120c8613e74565b60048111156120d9576120d9613e74565b81526040805160e08101909152600183018054602090930192829060ff16600281111561210857612108613e74565b600281111561211957612119613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c09092019161217090614189565b80601f016020809104026020016040519081016040528092919081815260200182805461219c90614189565b80156121e95780601f106121be576101008083540402835291602001916121e9565b820191906000526020600020905b8154815290600101906020018083116121cc57829003601f168201915b50505050508152505081526020016007820180548060200260200160405190810160405280929190818152602001828054801561224f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612231575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b8282101561232957838290600052602060002001805461229c90614189565b80601f01602080910402602001604051908101604052809291908181526020018280546122c890614189565b80156123155780601f106122ea57610100808354040283529160200191612315565b820191906000526020600020905b8154815290600101906020018083116122f857829003601f168201915b50505050508152602001906001019061227d565b505050908252506009919091015460209091015290506000602082015151600281111561235857612358613e74565b036123665750600092915050565b60028151600481111561237b5761237b613e74565b036123895750600192915050565b60048151600481111561239e5761239e613e74565b036123ac5750600092915050565b6001815160048111156123c1576123c1613e74565b146123cf5750600092915050565b8060400151516000036123e55750600092915050565b806060015151816040015151146123ff5750600092915050565b604080820151606083015160008054935161190160f01b6020820152602281019490945260428401879052928392919083906062016040516020818303038152906040528051906020012090505b81518510156125ca5760006001600160a01b031683868151811061247357612473614352565b60200260200101516001600160a01b031603156125bf576124c783868151811061249f5761249f614352565b6020026020010151828488815181106124ba576124ba614352565b602002602001015161349a565b6124d957506000979650505050505050565b600260208701515160028111156124f2576124f2613e74565b1461250757612502846001614328565b6125bc565b60025483516001600160a01b039091169062fdd58e9085908890811061252f5761252f614352565b60200260200101518860200151606001516040518363ffffffff1660e01b81526004016125719291906001600160a01b03929092168252602082015260400190565b602060405180830381865afa15801561258e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b29190614420565b6125bc9085614328565b93505b84600101945061244d565b831561272d57600260208701515160028111156125e9576125e9613e74565b03612683576002805460208801516060015160405163bd85b03960e01b81526001600160a01b039092169163bd85b0399161262a9160040190815260200190565b602060405180830381865afa158015612647573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061266b9190614420565b6126759190614439565b909311979650505050505050565b6001602087015151600281111561269c5761269c613e74565b0361272d576002805460208801516060015160405163eef2e75760e01b81526001600160a01b039092169163eef2e757916126dd9160040190815260200190565b600060405180830381865afa1580156126fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612722919081019061445b565b516126759190614439565b506000979650505050505050565b6002546001600160a01b031661276757600280546001600160a01b0319166001600160a01b0383161790555b6001546001600160a01b0316330361279557600280546001600160a01b0319166001600160a01b0383161790555b6040516001600160a01b03821681527f68e0e5615e0f0beac903df596e5f37d76055e23925dde4e747a159ed0170424f9060200160405180910390a150565b6002546001600160a01b031633146127ff576040516366e928db60e11b815260040160405180910390fd5b600083815260036020526040808220815160a081019092528054829060ff16600481111561282f5761282f613e74565b600481111561284057612840613e74565b81526040805160e08101909152600183018054602090930192829060ff16600281111561286f5761286f613e74565b600281111561288057612880613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c0909201916128d790614189565b80601f016020809104026020016040519081016040528092919081815260200182805461290390614189565b80156129505780601f1061292557610100808354040283529160200191612950565b820191906000526020600020905b81548152906001019060200180831161293357829003601f168201915b5050505050815250508152602001600782018054806020026020016040519081016040528092919081815260200182805480156129b657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612998575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015612a90578382906000526020600020018054612a0390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054612a2f90614189565b8015612a7c5780601f10612a5157610100808354040283529160200191612a7c565b820191906000526020600020905b815481529060010190602001808311612a5f57829003601f168201915b5050505050815260200190600101906129e4565b5050505081526020016009820154815250509050816001600160a01b031681604001518481518110612ac457612ac4614352565b60200260200101516001600160a01b031614612af35760405163490be95360e11b815260040160405180910390fd5b80606001518381518110612b0957612b09614352565b60200260200101606081525080604001518381518110612b2b57612b2b614352565b6000602091820292909201810182905285825260039052604090208151815483929190829060ff19166001836004811115612b6857612b68613e74565b02179055506020820151805160018084018054909291839160ff191690836002811115612b9757612b97613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c08201516005820190612c0e9082614214565b50505060408201518051612c2c916007840191602090910190613751565b5060608201518051612c489160088401916020909101906137b6565b50608091909101516009909101556000600681612c6e6001600160a01b03861688614368565b81526020808201929092526040908101600020805460ff191693151593909317909255828101516060015191516001600160a01b03851681528692917f72e8bb41de86f6a048361bf7dda6aee93fedcc6e8ac99520b47e6f289eb449d8910160405180910390a350505050565b60007fd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac5647282600001518051906020012083602001518051906020012084604001518560600151866080015160405160200161184b969594939291909586526020860194909452604085019290925260608401526001600160a01b0316608083015260a082015260c00190565b612d6e613808565b60008281526003602052604090819020815160a081019092528054829060ff166004811115612d9f57612d9f613e74565b6004811115612db057612db0613e74565b81526040805160e08101909152600183018054602090930192829060ff166002811115612ddf57612ddf613e74565b6002811115612df057612df0613e74565b815281546001600160a01b036101009091048116602083015260018301541660408201526002820154606082015260038201546080820152600482015460a082015260058201805460c090920191612e4790614189565b80601f0160208091040260200160405190810160405280929190818152602001828054612e7390614189565b8015612ec05780601f10612e9557610100808354040283529160200191612ec0565b820191906000526020600020905b815481529060010190602001808311612ea357829003601f168201915b505050505081525050815260200160078201805480602002602001604051908101604052809291908181526020018280548015612f2657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f08575b5050505050815260200160088201805480602002602001604051908101604052809291908181526020016000905b82821015613000578382906000526020600020018054612f7390614189565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9f90614189565b8015612fec5780601f10612fc157610100808354040283529160200191612fec565b820191906000526020600020905b815481529060010190602001808311612fcf57829003601f168201915b505050505081526020019060010190612f54565b505050508152602001600982015481525050905042816020015160800151116131465760048082526000838152600360205260409020825181548493839160ff191690600190849081111561305757613057613e74565b02179055506020820151805160018084018054909291839160ff19169083600281111561308657613086613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906130fd9082614214565b5050506040820151805161311b916007840191602090910190613751565b50606082015180516131379160088401916020909101906137b6565b50608082015181600901559050505b600061315582602001516117e7565b905061316081612094565b61317d57604051631150cdbd60e11b815260040160405180910390fd5b6002825260008381526003602052604090208251815484929190829060ff191660018360048111156131b1576131b1613e74565b02179055506020820151805160018084018054909291839160ff1916908360028111156131e0576131e0613e74565b021790555060208201518154610100600160a81b0319166101006001600160a01b039283160217825560408301516001830180546001600160a01b03191691909216179055606082015160028201556080820151600382015560a0820151600482015560c082015160058201906132579082614214565b50505060408201518051613275916007840191602090910190613751565b50606082015180516132919160088401916020909101906137b6565b506080820151816009015590505050919050565b6000632e14dcd360e21b81356001600160e01b0319160161330c576132cb8460036134fb565b90506001600160a01b03841630146132ec57836001600160a01b03166132ee565b825b6001600160a01b038216600090815260056020526040902055613334565b61331630836134fb565b6001600160a01b038116600090815260056020526040902084905590505b600254604051631465471360e11b81526001600160a01b038381166004830152602482018690528681166044830152909116906328ca8e2690606401600060405180830381600087803b15801561338a57600080fd5b505af115801561339e573d6000803e3d6000fd5b505050509392505050565b600080600083516041146134045760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e677468000000000000000060448201526064015b60405180910390fd5b50505060208101516040820151606083015160001a9190601b8310156134325761342f601b846144f5565b92505b8260ff16601b148061344757508260ff16601c145b6134935760405162461bcd60e51b815260206004820152601b60248201527f496e76616c6964207369676e6174757265202776272076616c7565000000000060448201526064016133fb565b9193909250565b60008060006134a98585613547565b909250905060008160048111156134c2576134c2613e74565b1480156134e05750856001600160a01b0316826001600160a01b0316145b806134f157506134f186868661358c565b9695505050505050565b6000828260405161350b9061388b565b6001600160a01b03909216825260ff166020820152604001604051809103906000f08015801561353f573d6000803e3d6000fd5b509392505050565b600080825160410361357d5760208301516040840151606085015160001a6135718782858561368d565b94509450505050613585565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b86866040516024016135b692919061450e565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990941693909317909252905161360991906142d4565b600060405180830381855afa9150503d8060008114613644576040519150601f19603f3d011682016040523d82523d6000602084013e613649565b606091505b509150915081801561365d57506020815110155b80156134f157508051630b135d3f60e11b906136829083016020908101908401614420565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156136c45750600090506003613748565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613718573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661374157600060019250925050613748565b9150600090505b94509492505050565b8280548282559060005260206000209081019282156137a6579160200282015b828111156137a657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613771565b506137b2929150613898565b5090565b8280548282559060005260206000209081019282156137fc579160200282015b828111156137fc57825182906137ec9082614214565b50916020019190600101906137d6565b506137b29291506138ad565b6040805160a0810190915280600081526020016138716040805160e08101909152806000815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008019168152602001606081525090565b815260606020820181905260408201819052600091015290565b610a028061452883390190565b5b808211156137b25760008155600101613899565b808211156137b25760006138c182826138ca565b506001016138ad565b5080546138d690614189565b6000825580601f106138e6575050565b601f0160209004906000526020600020908101906139049190613898565b50565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561394057613940613907565b60405290565b60405160a0810167ffffffffffffffff8111828210171561394057613940613907565b604051601f8201601f1916810167ffffffffffffffff8111828210171561399257613992613907565b604052919050565b600082601f8301126139ab57600080fd5b813567ffffffffffffffff8111156139c5576139c5613907565b6139d8601f8201601f1916602001613969565b8181528460208386010111156139ed57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613a1d57600080fd5b82359150602083013567ffffffffffffffff811115613a3b57600080fd5b613a478582860161399a565b9150509250929050565b600060208284031215613a6357600080fd5b5035919050565b803560038110613a7957600080fd5b919050565b6001600160a01b038116811461390457600080fd5b8035613a7981613a7e565b600060e08284031215613ab057600080fd5b613ab861391d565b9050613ac382613a6a565b8152613ad160208301613a93565b6020820152613ae260408301613a93565b6040820152606082013560608201526080820135608082015260a082013560a082015260c082013567ffffffffffffffff811115613b1f57600080fd5b613b2b8482850161399a565b60c08301525092915050565b60ff8116811461390457600080fd5b600080600080600060a08688031215613b5e57600080fd5b853567ffffffffffffffff811115613b7557600080fd5b613b8188828901613a9e565b9550506020860135613b9281613b37565b935060408601359250606086013591506080860135613bb081613a7e565b809150509295509295909350565b600080600060608486031215613bd357600080fd5b8335613bde81613a7e565b9250602084013591506040840135613bf581613a7e565b809150509250925092565b600067ffffffffffffffff821115613c1a57613c1a613907565b5060051b60200190565b600082601f830112613c3557600080fd5b81356020613c4a613c4583613c00565b613969565b82815260059290921b84018101918181019086841115613c6957600080fd5b8286015b84811015613ca957803567ffffffffffffffff811115613c8d5760008081fd5b613c9b8986838b010161399a565b845250918301918301613c6d565b509695505050505050565b600080600060608486031215613cc957600080fd5b8335925060208085013567ffffffffffffffff80821115613ce957600080fd5b818701915087601f830112613cfd57600080fd5b8135613d0b613c4582613c00565b81815260059190911b8301840190848101908a831115613d2a57600080fd5b938501935b82851015613d51578435613d4281613a7e565b82529385019390850190613d2f565b965050506040870135925080831115613d6957600080fd5b5050613d7786828701613c24565b9150509250925092565b600060208284031215613d9357600080fd5b8135613d9e81613a7e565b9392505050565b600080600080600080600060e0888a031215613dc057600080fd5b8735613dcb81613a7e565b96506020880135613ddb81613b37565b955060408801359450606088013593506080880135613df981613a7e565b925060a0880135915060c088013567ffffffffffffffff811115613e1c57600080fd5b613e288a828b0161399a565b91505092959891949750929550565b600060208284031215613e4957600080fd5b813567ffffffffffffffff811115613e6057600080fd5b613e6c84828501613a9e565b949350505050565b634e487b7160e01b600052602160045260246000fd5b60038110613e9a57613e9a613e74565b9052565b60005b83811015613eb9578181015183820152602001613ea1565b50506000910152565b60008151808452613eda816020860160208601613e9e565b601f01601f19169290920160200192915050565b60008151808452602080850194506020840160005b83811015613f285781516001600160a01b031687529582019590820190600101613f03565b509495945050505050565b60008282518085526020808601955060208260051b8401016020860160005b84811015613f8057601f19868403018952613f6e838351613ec2565b98840198925090830190600101613f52565b5090979650505050505050565b602081526000825160058110613fa557613fa5613e74565b80602084015250602083015160a06040840152613fc660c084018251613e8a565b60208101516001600160a01b0380821660e08601528060408401511661010086015250506060810151610120840152608081015161014084015260a081015161016084015260c0810151905060e06101808401526140286101a0840182613ec2565b90506040840151601f19808584030160608601526140468383613eee565b92506060860151915080858403016080860152506140648282613f33565b915050608084015160a08401528091505092915050565b6000806040838503121561408e57600080fd5b50508035926020909101359150565b6000806000606084860312156140b257600080fd5b83359250602084013591506040840135613bf581613a7e565b6000602082840312156140dd57600080fd5b813567ffffffffffffffff808211156140f557600080fd5b9083019060a0828603121561410957600080fd5b614111613946565b82358281111561412057600080fd5b61412c8782860161399a565b82525060208301358281111561414157600080fd5b61414d8782860161399a565b602083015250604083013560408201526060830135915061416d82613a7e565b8160608201526080830135608082015280935050505092915050565b600181811c9082168061419d57607f821691505b6020821081036141bd57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561420f576000816000526020600020601f850160051c810160208610156141ec5750805b601f850160051c820191505b8181101561420b578281556001016141f8565b5050505b505050565b815167ffffffffffffffff81111561422e5761422e613907565b6142428161423c8454614189565b846141c3565b602080601f831160018114614277576000841561425f5750858301515b600019600386901b1c1916600185901b17855561420b565b600085815260208120601f198616915b828110156142a657888601518255948401946001909101908401614287565b50858210156142c45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082516142e6818460208701613e9e565b9190910192915050565b60006020828403121561430257600080fd5b81518015158114613d9e57600080fd5b634e487b7160e01b600052601160045260246000fd5b8082018082111561049257610492614312565b808202811582820484141761049257610492614312565b634e487b7160e01b600052603260045260246000fd5b8181038181111561049257610492614312565b60006001820161438d5761438d614312565b5060010190565b6000602082840312156143a657600080fd5b8151613d9e81613a7e565b6000602082840312156143c357600080fd5b8151613d9e81613b37565b88815261010081016143e3602083018a613e8a565b6001600160a01b039788166040830152959096166060870152608086019390935260a085019190915260c084015260e09092019190915292915050565b60006020828403121561443257600080fd5b5051919050565b60008261445657634e487b7160e01b600052601260045260246000fd5b500490565b6000602080838503121561446e57600080fd5b825167ffffffffffffffff81111561448557600080fd5b8301601f8101851361449657600080fd5b80516144a4613c4582613c00565b81815260059190911b820183019083810190878311156144c357600080fd5b928401925b828410156144ea5783516144db81613a7e565b825292840192908401906144c8565b979650505050505050565b60ff818116838216019081111561049257610492614312565b828152604060208201526000613e6c6040830184613ec256fe60a0604052348015600f57600080fd5b50604051610a02380380610a02833981016040819052602c916057565b600080546001600160a01b0319166001600160a01b03939093169290921790915560ff1660805260a0565b60008060408385031215606957600080fd5b82516001600160a01b0381168114607f57600080fd5b602084015190925060ff81168114609557600080fd5b809150509250929050565b6080516109476100bb60003960006101a801526109476000f3fe60806040526004361061009a5760003560e01c80638da5cb5b11610069578063cb2f1df31161004e578063cb2f1df314610261578063d784d42614610281578063f23a6e61146102a1576100a1565b80638da5cb5b14610214578063bce38bd714610234576100a1565b806313af4035146101205780631626ba7e1461014057806334e0bebe146101965780635c60da1b146101dc576100a1565b366100a157005b60003560e01c63bc197c81811463f23a6e6182141763150b7a02821417156100cd57806020526020603cf35b506001546001600160a01b03166100f757604051631174132960e21b815260040160405180910390fd5b6001543660008037600080366000845af43d6000803e808015610119573d6000f35b3d6000fd5b005b34801561012c57600080fd5b5061011e61013b3660046105f2565b6102ce565b34801561014c57600080fd5b5061016061015b366004610656565b610328565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b3480156101a257600080fd5b506101ca7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161018d565b3480156101e857600080fd5b506001546101fc906001600160a01b031681565b6040516001600160a01b03909116815260200161018d565b34801561022057600080fd5b506000546101fc906001600160a01b031681565b34801561024057600080fd5b5061025461024f3660046106a2565b610350565b60405161018d919061072f565b34801561026d57600080fd5b5061011e61027c3660046107dd565b61051f565b34801561028d57600080fd5b5061011e61029c3660046105f2565b61056a565b3480156102ad57600080fd5b506101606102bc3660046107f6565b63f23a6e6160e01b9695505050505050565b6000546001600160a01b031633146102f9576040516330cd747160e01b815260040160405180910390fd5b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60008381526002602052604081205460ff16156103495750630b135d3f60e11b5b9392505050565b6000546060906001600160a01b0316331461037e576040516330cd747160e01b815260040160405180910390fd5b8167ffffffffffffffff8111156103975761039761086e565b6040519080825280602002602001820160405280156103dd57816020015b6040805180820190915260008152606060208201528152602001906001900390816103b55790505b50905060005b828110156105175760008085858481811061040057610400610884565b9050602002810190610412919061089a565b6104209060208101906105f2565b6001600160a01b031686868581811061043b5761043b610884565b905060200281019061044d919061089a565b61045b9060208101906108ba565b604051610469929190610901565b6000604051808303816000865af19150503d80600081146104a6576040519150601f19603f3d011682016040523d82523d6000602084013e6104ab565b606091505b50915091508680156104bb575081155b156104d95760405163177a8f7f60e11b815260040160405180910390fd5b604051806040016040528083151581526020018281525084848151811061050257610502610884565b602090810291909101015250506001016103e3565b509392505050565b6000546001600160a01b0316331461054a576040516330cd747160e01b815260040160405180910390fd5b6000908152600260205260409020805460ff19811660ff90911615179055565b6000546001600160a01b03163314610595576040516330cd747160e01b815260040160405180910390fd5b6001546001600160a01b038281169116146105d3576001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383161790555b50565b80356001600160a01b03811681146105ed57600080fd5b919050565b60006020828403121561060457600080fd5b610349826105d6565b60008083601f84011261061f57600080fd5b50813567ffffffffffffffff81111561063757600080fd5b60208301915083602082850101111561064f57600080fd5b9250929050565b60008060006040848603121561066b57600080fd5b83359250602084013567ffffffffffffffff81111561068957600080fd5b6106958682870161060d565b9497909650939450505050565b6000806000604084860312156106b757600080fd5b833580151581146106c757600080fd5b9250602084013567ffffffffffffffff808211156106e457600080fd5b818601915086601f8301126106f857600080fd5b81358181111561070757600080fd5b8760208260051b850101111561071c57600080fd5b6020830194508093505050509250925092565b600060208083018184528085518083526040925060408601915060408160051b8701018488016000805b848110156107ce57898403603f1901865282518051151585528801518885018890528051888601819052835b818110156107a1578281018b0151878201606001528a01610785565b508581016060908101859052978a0197601f909101601f1916909501909401935091870191600101610759565b50919998505050505050505050565b6000602082840312156107ef57600080fd5b5035919050565b60008060008060008060a0878903121561080f57600080fd5b610818876105d6565b9550610826602088016105d6565b94506040870135935060608701359250608087013567ffffffffffffffff81111561085057600080fd5b61085c89828a0161060d565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235603e198336030181126108b057600080fd5b9190910192915050565b6000808335601e198436030181126108d157600080fd5b83018035915067ffffffffffffffff8211156108ec57600080fd5b60200191503681900382131561064f57600080fd5b818382376000910190815291905056fea2646970667358221220395efa67fb5c0c6ef2a85441ecb434b818f7b9186748556c0621251a1adbaf6a64736f6c63430008190033a264697066735822122006cd09e264550c4cd1d7c5125a4882591338e64fbf26f9e6001b8d95cbdb306e64736f6c63430008190033