From 485c6a77b696a3f73e6a7a4b914d98b68d905941 Mon Sep 17 00:00:00 2001 From: konstantinabl Date: Tue, 1 Oct 2024 11:03:24 +0300 Subject: [PATCH] feat: add new tests for HIP-1010 (#911) * Exposes new update fees methods through HTS and wrapper contract Signed-off-by: Konstantina Blazhukova * Allows passing of custom fee arrays in TokenCreateCustom contract Signed-off-by: Konstantina Blazhukova * Adds necessary methods for tests and adds fee key to creation methods Signed-off-by: Konstantina Blazhukova * Adds artifacts and abis for new and updated contracts Signed-off-by: Konstantina Blazhukova * Adds util functions Signed-off-by: Konstantina Blazhukova * Removes console logs, makes code more modular and readable Signed-off-by: Konstantina Blazhukova * Fixes failing update fees tests Signed-off-by: Konstantina Blazhukova * Fixes some tests and adds new ones Signed-off-by: Konstantina Blazhukova * Fixes tests Signed-off-by: Konstantina Blazhukova * Fixes multiple fracitonal fees test Signed-off-by: Konstantina Blazhukova * bumps local node version Signed-off-by: Konstantina Blazhukova * Fixes updating of token keys in hip583 test Signed-off-by: Konstantina Blazhukova * Fixes failing erc20 tests Signed-off-by: Konstantina Blazhukova * Removes leftover console log Signed-off-by: Konstantina Blazhukova * Adds solidity doc to IHederaTokenService for new methods Signed-off-by: Konstantina Blazhukova --------- Signed-off-by: Konstantina Blazhukova --- .../TokenCreateContract.json | 4 +- .../TokenCreateCustomContract.json | 231 ++- .../TokenManagementContract.json | 180 ++- .../TokenQueryContract.json | 4 +- .../TokenTransferContract.json | 52 +- .../IHederaTokenService.json | 176 +++ .../TokenCreateCustomContract.json | 227 ++- .../TokenManagementContract.json | 176 +++ .../TokenTransferContract.json | 48 + .../HederaTokenService.sol | 22 + .../IHederaTokenService.sol | 14 + .../token-create/TokenCreateContract.sol | 15 +- .../token-create/TokenCreateCustom.sol | 68 +- .../token-manage/TokenManagementContract.sol | 27 + .../token-transfer/TokenTransferContract.sol | 18 + package-lock.json | 15 +- package.json | 2 +- test/hip-583/HIP583.js | 8 + .../erc-20/ERC20Contract.js | 4 +- .../hedera-token-service/erc-20/IERC20.js | 4 +- .../token-create/tokenCreateContract.js | 6 +- .../token-managment/tokenManagmentContract.js | 1331 ++++++++++++++++- test/precompile/hedera-token-service/utils.js | 184 ++- 23 files changed, 2730 insertions(+), 86 deletions(-) diff --git a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol/TokenCreateContract.json b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol/TokenCreateContract.json index bfb9bde07..2df25ceec 100644 --- a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol/TokenCreateContract.json +++ b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol/TokenCreateContract.json @@ -653,8 +653,8 @@ "type": "function" } ], - "bytecode": "0x60c06040526009608090815268746f6b656e4e616d6560b81b60a0526002906200002a908262000261565b5060408051808201909152600b81526a1d1bdad95b94de5b589bdb60aa1b60208201526003906200005c908262000261565b50604080518082019091526004808252636d656d6f60e01b60208301529062000086908262000261565b50600580546001600160a81b0319167008000000000000271000000000000003e8179055348015620000b6575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a556200032d565b634e487b7160e01b5f52604160045260245ffd5b600181811c90821680620001ec57607f821691505b6020821081036200020b57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156200025c57805f5260205f20601f840160051c81016020851015620002385750805b601f840160051c820191505b8181101562000259575f815560010162000244565b50505b505050565b81516001600160401b038111156200027d576200027d620001c3565b62000295816200028e8454620001d7565b8462000211565b602080601f831160018114620002cb575f8415620002b35750858301515b5f19600386901b1c1916600185901b17855562000325565b5f85815260208120601f198616915b82811015620002fb57888601518255948401946001909101908401620002da565b50858210156200031957878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b613d06806200033b5f395ff3fe608060405260043610610110575f3560e01c80638ba74da01161009d578063d85f74c111610062578063d85f74c1146102cf578063de84a779146102e2578063e9f7322614610301578063f4a01e5b14610314578063f848fec414610333575f80fd5b80638ba74da01461024c5780638f74a17b1461025f5780639b23d3d91461028a578063b35d417a146102a9578063cc265af4146102bc575f80fd5b806336348de3116100e357806336348de3146101ac5780634b5c6687146101cb5780634d1769d6146101de578063618dc65e1461020c57806371de370714610239575f80fd5b80630488c939146101145780630fd2601e14610129578063118741e71461016057806315dacbea1461018d575b5f80fd5b610127610122366004612d60565b610352565b005b348015610134575f80fd5b50610148610143366004612d60565b6108a4565b60405160079190910b81526020015b60405180910390f35b34801561016b575f80fd5b5061017f61017a366004612e6f565b6108ff565b604051908152602001610157565b348015610198575f80fd5b506101486101a7366004612f1e565b610951565b3480156101b7575f80fd5b5061017f6101c63660046131cd565b610a40565b6101276101d936600461330d565b610a4b565b3480156101e9575f80fd5b506101fd6101f8366004613328565b610e3b565b60405161015793929190613435565b348015610217575f80fd5b5061022b61022636600461345f565b610ef9565b6040516101579291906134f9565b610127610247366004613519565b611010565b61012761025a366004612d60565b61116c565b61027261026d36600461345f565b6115c0565b6040516001600160a01b039091168152602001610157565b348015610295575f80fd5b506101486102a4366004612f1e565b611974565b6101276102b736600461345f565b6119b8565b6101276102ca36600461345f565b611d50565b6101276102dd36600461330d565b611e24565b3480156102ed575f80fd5b506101fd6102fc366004613328565b6121a8565b61027261030f36600461345f565b612240565b34801561031f575f80fd5b5061017f61032e366004612d60565b612317565b34801561033e575f80fd5b5061017f61034d366004613579565b612322565b60408051600580825260c082019092525f91816020015b610371612ce0565b8152602001906001900390816103695790505090506103a15f60065f60405180602001604052805f81525061237c565b815f815181106103b3576103b36135b7565b60200260200101819052506103d860015f60405180602001604052805f8152506123b3565b816001815181106103eb576103eb6135b7565b602002602001018190525061041060025f60405180602001604052805f8152506123b3565b81600281518110610423576104236135b7565b602002602001018190525061044860045f60405180602001604052805f8152506123b3565b8160038151811061045b5761045b6135b7565b602002602001018190525061048060035f60405180602001604052805f8152506123b3565b81600481518110610493576104936135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f604051806101200160405280600280546104e8906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610514906135cb565b801561055f5780601f106105365761010080835404028352916020019161055f565b820191905f5260205f20905b81548152906001019060200180831161054257829003601f168201915b5050505050815260200160038054610576906135cb565b80601f01602080910402602001604051908101604052809291908181526020018280546105a2906135cb565b80156105ed5780601f106105c4576101008083540402835291602001916105ed565b820191905f5260205f20905b8154815290600101906020018083116105d057829003601f168201915b50505050508152602001866001600160a01b0316815260200160048054610613906135cb565b80601f016020809104026020016040519081016040528092919081815260200182805461063f906135cb565b801561068a5780601f106106615761010080835404028352916020019161068a565b820191905f5260205f20905b81548152906001019060200180831161066d57829003601f168201915b5050509183525050600160208201819052600554600160401b810460070b6040840152600160a01b900460ff16151560608301526080820186905260a09091018490529091505f9060405190808252806020026020018201604052801561072957816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816106f05790505b506040805160a081018252600181526001600160a01b0380891660208301525f9282018390526060820183905289166080820152825192935091839190610772576107726135b7565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816107935790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b8152602001876001600160a01b031681526020015f15158152602001886001600160a01b0316815250815f81518110610834576108346135b7565b60200260200101819052505f8061084c8585856123e8565b90925090506016821461085d575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b5f6108af8383612508565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146108f9575f80fd5b92915050565b5f61090a83836125e6565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161093d91815260200190565b60405180910390a1601681146108f9575f80fd5b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109cf9190613603565b5f604051808303815f865af19150503d805f8114610a08576040519150601f19603f3d011682016040523d82523d5f602084013e610a0d565b606091505b509150915081610a1e576015610a32565b80806020019051810190610a32919061362f565b60030b979650505050505050565b5f61090a8383612610565b60408051600580825260c082019092525f91816020015b610a6a612ce0565b815260200190600190039081610a62579050509050610a9a5f60065f60405180602001604052805f81525061237c565b815f81518110610aac57610aac6135b7565b6020026020010181905250610ad160015f60405180602001604052805f8152506123b3565b81600181518110610ae457610ae46135b7565b6020026020010181905250610b0960025f60405180602001604052805f8152506123b3565b81600281518110610b1c57610b1c6135b7565b6020026020010181905250610b4160035f60405180602001604052805f8152506123b3565b81600381518110610b5457610b546135b7565b6020026020010181905250610b7960045f60405180602001604052805f8152506123b3565b81600481518110610b8c57610b8c6135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054610be1906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0d906135cb565b8015610c585780601f10610c2f57610100808354040283529160200191610c58565b820191905f5260205f20905b815481529060010190602001808311610c3b57829003601f168201915b5050505050815260200160038054610c6f906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9b906135cb565b8015610ce65780601f10610cbd57610100808354040283529160200191610ce6565b820191905f5260205f20905b815481529060010190602001808311610cc957829003601f168201915b50505050508152602001856001600160a01b0316815260200160048054610d0c906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610d38906135cb565b8015610d835780601f10610d5a57610100808354040283529160200191610d83565b820191905f5260205f20905b815481529060010190602001808311610d6657829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f918291610de691859181900b90600160801b900460030b61263a565b909250905060168214610df7575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b5f806060610e4a8686866126a3565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610e91575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610ec2929190613648565b60405180910390a1610eef863033845f81518110610ee257610ee26135b7565b602002602001015161279a565b5093509350939050565b5f60605f806101676001600160a01b031663618dc65e60e01b8787604051602401610f25929190613663565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f639190613603565b5f604051808303815f865af19150503d805f8114610f9c576040519150601f19603f3d011682016040523d82523d5f602084013e610fa1565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc8282604051610fd7929190613684565b60405180910390a181610ffa57601560405180602001604052805f815250610ffe565b6016815b60039190910b97909650945050505050565b604051638f74a17b60e01b81525f903090638f74a17b9034906110399088908890600401613663565b60206040518083038185885af1158015611055573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061107a919061369e565b60405163f4a01e5b60e01b81523360048201526001600160a01b0382166024820152909150309063f4a01e5b906044016020604051808303815f875af11580156110c6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110ea91906136b9565b506040516307e9300f60e11b81526001600160a01b03821660048201523360248201523090630fd2601e906044016020604051808303815f875af1158015611134573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115891906136d0565b50611165813033856127e1565b5050505050565b6040805160018082528183019092525f91816020015b61118a612ce0565b8152602001906001900390816111825790505090506111b95f805f60405180602001604052805f81525061237c565b815f815181106111cb576111cb6135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611220906135cb565b80601f016020809104026020016040519081016040528092919081815260200182805461124c906135cb565b80156112975780601f1061126e57610100808354040283529160200191611297565b820191905f5260205f20905b81548152906001019060200180831161127a57829003601f168201915b50505050508152602001600380546112ae906135cb565b80601f01602080910402602001604051908101604052809291908181526020018280546112da906135cb565b80156113255780601f106112fc57610100808354040283529160200191611325565b820191905f5260205f20905b81548152906001019060200180831161130857829003601f168201915b50505050508152602001866001600160a01b031681526020016004805461134b906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611377906135cb565b80156113c25780601f10611399576101008083540402835291602001916113c2565b820191905f5260205f20905b8154815290600101906020018083116113a557829003601f168201915b5050509183525050600160208201819052600554600160401b900460070b6040808401919091525f606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816114165750506040805160a081018252600181526001600160a01b0388811660208301525f9282018390526060820183905289166080820152825192935091839190611496576114966135b7565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816114b75750506040805160c0810182526004815260056020820152600a91810191909152601e60608201525f608082018190526001600160a01b038a1660a083015282519293509091839190611548576115486135b7565b60209081029190910101526005545f908190611577908690600781900b90600160801b900460030b8787612828565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa826040516115ac91815260200190565b60405180910390a16016821461085d575f80fd5b60408051600580825260c082019092525f91829190816020015b6115e2612ce0565b8152602001906001900390816115da5790505090506116055f600660038661237c565b815f81518110611617576116176135b7565b602002602001018190525061162f60016003856123b3565b81600181518110611642576116426135b7565b602002602001018190525061165a60026003856123b3565b8160028151811061166d5761166d6135b7565b602002602001018190525061168560046003856123b3565b81600381518110611698576116986135b7565b60200260200101819052506116af600380856123b3565b816004815181106116c2576116c26135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001866001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611717906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611743906135cb565b801561178e5780601f106117655761010080835404028352916020019161178e565b820191905f5260205f20905b81548152906001019060200180831161177157829003601f168201915b50505050508152602001600380546117a5906135cb565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906135cb565b801561181c5780601f106117f35761010080835404028352916020019161181c565b820191905f5260205f20905b8154815290600101906020018083116117ff57829003601f168201915b50505050508152602001876001600160a01b0316815260200160048054611842906135cb565b80601f016020809104026020016040519081016040528092919081815260200182805461186e906135cb565b80156118b95780601f10611890576101008083540402835291602001916118b9565b820191905f5260205f20905b81548152906001019060200180831161189c57829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f91829161191c91859181900b90600160801b900460030b61263a565b90925090506016821461192d575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1979650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610991565b60408051600580825260c082019092525f91816020015b6119d7612ce0565b8152602001906001900390816119cf5790505090506119fa5f600660038561237c565b815f81518110611a0c57611a0c6135b7565b6020026020010181905250611a2460016003846123b3565b81600181518110611a3757611a376135b7565b6020026020010181905250611a4f60026003846123b3565b81600281518110611a6257611a626135b7565b6020026020010181905250611a7a60046003846123b3565b81600381518110611a8d57611a8d6135b7565b6020026020010181905250611aa4600380846123b3565b81600481518110611ab757611ab76135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611b0c906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906135cb565b8015611b835780601f10611b5a57610100808354040283529160200191611b83565b820191905f5260205f20905b815481529060010190602001808311611b6657829003601f168201915b5050505050815260200160038054611b9a906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc6906135cb565b8015611c115780601f10611be857610100808354040283529160200191611c11565b820191905f5260205f20905b815481529060010190602001808311611bf457829003601f168201915b50505050508152602001866001600160a01b0316815260200160048054611c37906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611c63906135cb565b8015611cae5780601f10611c8557610100808354040283529160200191611cae565b820191905f5260205f20905b815481529060010190602001808311611c9157829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80611cfa8361294e565b909250905060168214611d0b575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050565b60408051600480825260a082019092525f91816020015b611d6f612ce0565b815260200190600190039081611d67579050509050611d925f600660038561237c565b815f81518110611da457611da46135b7565b6020026020010181905250611dbc60026003846123b3565b81600181518110611dcf57611dcf6135b7565b6020026020010181905250611de760046003846123b3565b81600281518110611dfa57611dfa6135b7565b6020026020010181905250611e11600380846123b3565b81600381518110611ab757611ab76135b7565b60408051600580825260c082019092525f91816020015b611e43612ce0565b815260200190600190039081611e3b579050509050611e735f60065f60405180602001604052805f81525061237c565b815f81518110611e8557611e856135b7565b6020026020010181905250611eaa60015f60405180602001604052805f8152506123b3565b81600181518110611ebd57611ebd6135b7565b6020026020010181905250611ee260025f60405180602001604052805f8152506123b3565b81600281518110611ef557611ef56135b7565b6020026020010181905250611f1a60045f60405180602001604052805f8152506123b3565b81600381518110611f2d57611f2d6135b7565b6020026020010181905250611f5260035f60405180602001604052805f8152506123b3565b81600481518110611f6557611f656135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611fba906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe6906135cb565b80156120315780601f1061200857610100808354040283529160200191612031565b820191905f5260205f20905b81548152906001019060200180831161201457829003601f168201915b5050505050815260200160038054612048906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054612074906135cb565b80156120bf5780601f10612096576101008083540402835291602001916120bf565b820191905f5260205f20905b8154815290600101906020018083116120a257829003601f168201915b50505050508152602001856001600160a01b03168152602001600480546120e5906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054612111906135cb565b801561215c5780601f106121335761010080835404028352916020019161215c565b820191905f5260205f20905b81548152906001019060200180831161213f57829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80610de68361294e565b5f8060606121b78686866126a3565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1601683146121fe575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d828260405161222f929190613648565b60405180910390a193509350939050565b60408051600480825260a082019092525f91829190816020015b612262612ce0565b81526020019060019003908161225a5790505090506122855f600660038661237c565b815f81518110612297576122976135b7565b60200260200101819052506122af60026003856123b3565b816001815181106122c2576122c26135b7565b60200260200101819052506122da60046003856123b3565b816002815181106122ed576122ed6135b7565b6020026020010181905250612304600380856123b3565b816003815181106116c2576116c26135b7565b5f61090a8383612a56565b5f61232e848484612a8b565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161236191815260200190565b60405180910390a160168114612375575f80fd5b9392505050565b612384612ce0565b60405180604001604052806123998787612b5f565b81526020016123a88585612b99565b905295945050505050565b6123bb612ce0565b60405180604001604052806123cf86612ca4565b81526020016123de8585612b99565b9052949350505050565b5f80848061010001515f015160070b5f14801561240f57506101008101516040015160070b155b15612425576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a6040516024016124519392919061391d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161248f9190613603565b5f6040518083038185875af1925050503d805f81146124c9576040519150601f19603f3d011682016040523d82523d5f602084013e6124ce565b606091505b5091509150816124e05760155f6124f4565b808060200190518101906124f491906139d4565b60039190910b999098509650505050505050565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516125779190613603565b5f604051808303815f865af19150503d805f81146125b0576040519150601f19603f3d011682016040523d82523d5f602084013e6125b5565b606091505b5091509150816125c65760156125da565b808060200190518101906125da919061362f565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b86866040516024016125399291906139fe565b5f805f6101676001600160a01b0316637d305cfa60e01b8686604051602401612539929190613a59565b5f80848061010001515f015160070b5f14801561266157506101008101516040015160070b155b15612677576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a60405160240161245193929190613a7a565b5f8060605f806101676001600160a01b031663e0f4059a60e01b8989896040516024016126d293929190613aa8565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516127109190613603565b5f604051808303815f865af19150503d805f8114612749576040519150601f19603f3d011682016040523d82523d5f602084013e61274e565b606091505b50915091508161277057604080515f8082526020820190925260159190612784565b808060200190518101906127849190613b25565b60039290920b9a90995090975095505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610991565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610991565b5f80868061010001515f015160070b5f14801561284f57506101008101516040015160070b155b15612865576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c604051602401612895959493929190613bdf565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516128d39190613603565b5f6040518083038185875af1925050503d805f811461290d576040519150601f19603f3d011682016040523d82523d5f602084013e612912565b606091505b5091509150816129245760155f612938565b8080602001905181019061293891906139d4565b60039190910b9b909a5098505050505050505050565b5f80828061010001515f015160070b5f14801561297557506101008101516040015160070b155b1561298b576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b886040516024016129b39190613caa565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516129f19190613603565b5f6040518083038185875af1925050503d805f8114612a2b576040519150601f19603f3d011682016040523d82523d5f602084013e612a30565b606091505b509150915081612a425760155f610ffe565b80806020019051810190610ffe91906139d4565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b90606401612539565b604080516001600160a01b03858116602483015284166044820152606480820184905282518083039091018152608490910182526020810180516001600160e01b031663e1f21c6760e01b17905290515f918291829161016791612aef9190613603565b5f604051808303815f865af19150503d805f8114612b28576040519150601f19603f3d011682016040523d82523d5f602084013e612b2d565b606091505b509150915081612b3e576015612b52565b80806020019051810190612b52919061362f565b60030b9695505050505050565b5f612b82836006811115612b7557612b75613cbc565b600160ff9091161b821790565b9050612375826006811115612b7557612b75613cbc565b612bdc6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b5f836004811115612bef57612bef613cbc565b03612bfd57600181526108f9565b6001836004811115612c1157612c11613cbc565b03612c2b575f546001600160a01b031660208201526108f9565b6002836004811115612c3f57612c3f613cbc565b03612c5057604081018290526108f9565b6003836004811115612c6457612c64613cbc565b03612c7557606081018290526108f9565b6004836004811115612c8957612c89613cbc565b036108f9575f546001600160a01b0316608082015292915050565b5f60015f836006811115612cba57612cba613cbc565b6006811115612ccb57612ccb613cbc565b81526020019081526020015f20549050919050565b60405180604001604052805f8152602001612d346040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b905290565b6001600160a01b0381168114612d4d575f80fd5b50565b8035612d5b81612d39565b919050565b5f8060408385031215612d71575f80fd5b8235612d7c81612d39565b91506020830135612d8c81612d39565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715612dce57612dce612d97565b60405290565b60405160a0810167ffffffffffffffff81118282101715612dce57612dce612d97565b604051610120810167ffffffffffffffff81118282101715612dce57612dce612d97565b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4457612e44612d97565b604052919050565b5f67ffffffffffffffff821115612e6557612e65612d97565b5060051b60200190565b5f8060408385031215612e80575f80fd5b8235612e8b81612d39565b915060208381013567ffffffffffffffff811115612ea7575f80fd5b8401601f81018613612eb7575f80fd5b8035612eca612ec582612e4c565b612e1b565b81815260059190911b82018301908381019088831115612ee8575f80fd5b928401925b82841015612f0f578335612f0081612d39565b82529284019290840190612eed565b80955050505050509250929050565b5f805f8060808587031215612f31575f80fd5b8435612f3c81612d39565b93506020850135612f4c81612d39565b92506040850135612f5c81612d39565b9396929550929360600135925050565b5f82601f830112612f7b575f80fd5b813567ffffffffffffffff811115612f9557612f95612d97565b612fa8601f8201601f1916602001612e1b565b818152846020838601011115612fbc575f80fd5b816020850160208301375f918101602001919091529392505050565b80358015158114612d5b575f80fd5b8060070b8114612d4d575f80fd5b8035612d5b81612fe7565b5f82601f83011261300f575f80fd5b8135602061301f612ec583612e4c565b82815260059290921b8401810191818101908684111561303d575f80fd5b8286015b8481101561314e57803567ffffffffffffffff80821115613060575f80fd5b908801906040601f19838c038101821315613079575f80fd5b613081612dab565b8885013581528285013584811115613097575f80fd5b949094019360a0858e03830112156130ad575f80fd5b6130b5612dd4565b91506130c2898601612fd8565b8252828501356130d181612d39565b828a0152606085810135858111156130e7575f80fd5b6130f58f8c838a0101612f6c565b858501525060809350838601358581111561310e575f80fd5b61311c8f8c838a0101612f6c565b82850152505060a0850135945061313285612d39565b9181019390935280870192909252508352918301918301613041565b509695505050505050565b5f60608284031215613169575f80fd5b6040516060810181811067ffffffffffffffff8211171561318c5761318c612d97565b604052905080823561319d81612fe7565b815260208301356131ad81612d39565b602082015260408301356131c081612fe7565b6040919091015292915050565b5f80604083850312156131de575f80fd5b82356131e981612d39565b9150602083013567ffffffffffffffff80821115613205575f80fd5b908401906101608287031215613219575f80fd5b613221612df7565b82358281111561322f575f80fd5b61323b88828601612f6c565b82525060208301358281111561324f575f80fd5b61325b88828601612f6c565b60208301525061326d60408401612d50565b6040820152606083013582811115613283575f80fd5b61328f88828601612f6c565b6060830152506132a160808401612fd8565b60808201526132b260a08401612ff5565b60a08201526132c360c08401612fd8565b60c082015260e0830135828111156132d9575f80fd5b6132e588828601613000565b60e08301525061010091506132fc87838501613159565b828201528093505050509250929050565b5f6020828403121561331d575f80fd5b813561237581612d39565b5f805f6060848603121561333a575f80fd5b833561334581612d39565b925060208481013561335681612fe7565b9250604085013567ffffffffffffffff80821115613372575f80fd5b818701915087601f830112613385575f80fd5b8135613393612ec582612e4c565b81815260059190911b8301840190848101908a8311156133b1575f80fd5b8585015b838110156133e7578035858111156133cb575f80fd5b6133d98d89838a0101612f6c565b8452509186019186016133b5565b508096505050505050509250925092565b5f815180845260208085019450602084015f5b8381101561342a57815160070b8752958201959082019060010161340b565b509495945050505050565b8381528260070b6020820152606060408201525f61345660608301846133f8565b95945050505050565b5f8060408385031215613470575f80fd5b823561347b81612d39565b9150602083013567ffffffffffffffff811115613496575f80fd5b6134a285828601612f6c565b9150509250929050565b5f5b838110156134c65781810151838201526020016134ae565b50505f910152565b5f81518084526134e58160208601602086016134ac565b601f01601f19169290920160200192915050565b828152604060208201525f61351160408301846134ce565b949350505050565b5f805f6060848603121561352b575f80fd5b833561353681612d39565b9250602084013567ffffffffffffffff811115613551575f80fd5b61355d86828701612f6c565b925050604084013561356e81612fe7565b809150509250925092565b5f805f6060848603121561358b575f80fd5b833561359681612d39565b925060208401356135a681612d39565b929592945050506040919091013590565b634e487b7160e01b5f52603260045260245ffd5b600181811c908216806135df57607f821691505b6020821081036135fd57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f82516136148184602087016134ac565b9190910192915050565b8051600381900b8114612d5b575f80fd5b5f6020828403121561363f575f80fd5b6123758261361e565b8260070b8152604060208201525f61351160408301846133f8565b6001600160a01b0383168152604060208201525f61351160408301846134ce565b8215158152604060208201525f61351160408301846134ce565b5f602082840312156136ae575f80fd5b815161237581612d39565b5f602082840312156136c9575f80fd5b5051919050565b5f602082840312156136e0575f80fd5b815161237581612fe7565b5f82825180855260208086019550808260051b8401018186015f5b848110156137a357601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a015261376560e08a01866134ce565b92860151898403603f1901858b015292945061378185846134ce565b9501511660c09790970196909652505098840198925090830190600101613706565b5090979650505050505050565b5f61016082518185526137c5828601826134ce565b915050602083015184820360208601526137df82826134ce565b91505060408301516137fc60408601826001600160a01b03169052565b506060830151848203606086015261381482826134ce565b915050608083015161382a608086018215159052565b5060a083015161383f60a086018260070b9052565b5060c083015161385360c086018215159052565b5060e083015184820360e086015261386b82826136eb565b915050610100808401516138a782870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b8381101561342a578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a090960195908201906001016138c4565b5f606080835261393060608401876137b0565b60208482038186015261394382886138b1565b915060408583036040870152828751808552838501915083890194505f5b818110156139c45785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c090920191600101613961565b50909a9950505050505050505050565b5f80604083850312156139e5575f80fd5b6139ee8361361e565b91506020830151612d8c81612d39565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015613a4b578551851683529483019491830191600101613a2d565b509098975050505050505050565b6001600160a01b0383168152604060208201525f61351160408301846137b0565b606081525f613a8c60608301866137b0565b90508360070b60208301528260030b6040830152949350505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b82811015613b1657607f19888703018452613b048683516134ce565b95509284019290840190600101613ae8565b50939998505050505050505050565b5f805f60608486031215613b37575f80fd5b613b408461361e565b9250602080850151613b5181612fe7565b604086015190935067ffffffffffffffff811115613b6d575f80fd5b8501601f81018713613b7d575f80fd5b8051613b8b612ec582612e4c565b81815260059190911b82018301908381019089831115613ba9575f80fd5b928401925b82841015613bd0578351613bc181612fe7565b82529284019290840190613bae565b80955050505050509250925092565b5f60a0808352613bf260a08401896137b0565b602060078960070b8287015260408960030b604088015260608785036060890152613c1d858b6138b1565b9450608088860360808a0152858a518088528688019150868c0197505f5b81811015613c955788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c090920191600101613c3b565b50909f9e505050505050505050505050505050565b602081525f61237560208301846137b0565b634e487b7160e01b5f52602160045260245ffdfea2646970667358221220575ca66fd032e49d40288cfcf0d06ab70232ab6ff9612ebd0dfeff08ba75b28664736f6c63430008180033", - "deployedBytecode": "0x608060405260043610610110575f3560e01c80638ba74da01161009d578063d85f74c111610062578063d85f74c1146102cf578063de84a779146102e2578063e9f7322614610301578063f4a01e5b14610314578063f848fec414610333575f80fd5b80638ba74da01461024c5780638f74a17b1461025f5780639b23d3d91461028a578063b35d417a146102a9578063cc265af4146102bc575f80fd5b806336348de3116100e357806336348de3146101ac5780634b5c6687146101cb5780634d1769d6146101de578063618dc65e1461020c57806371de370714610239575f80fd5b80630488c939146101145780630fd2601e14610129578063118741e71461016057806315dacbea1461018d575b5f80fd5b610127610122366004612d60565b610352565b005b348015610134575f80fd5b50610148610143366004612d60565b6108a4565b60405160079190910b81526020015b60405180910390f35b34801561016b575f80fd5b5061017f61017a366004612e6f565b6108ff565b604051908152602001610157565b348015610198575f80fd5b506101486101a7366004612f1e565b610951565b3480156101b7575f80fd5b5061017f6101c63660046131cd565b610a40565b6101276101d936600461330d565b610a4b565b3480156101e9575f80fd5b506101fd6101f8366004613328565b610e3b565b60405161015793929190613435565b348015610217575f80fd5b5061022b61022636600461345f565b610ef9565b6040516101579291906134f9565b610127610247366004613519565b611010565b61012761025a366004612d60565b61116c565b61027261026d36600461345f565b6115c0565b6040516001600160a01b039091168152602001610157565b348015610295575f80fd5b506101486102a4366004612f1e565b611974565b6101276102b736600461345f565b6119b8565b6101276102ca36600461345f565b611d50565b6101276102dd36600461330d565b611e24565b3480156102ed575f80fd5b506101fd6102fc366004613328565b6121a8565b61027261030f36600461345f565b612240565b34801561031f575f80fd5b5061017f61032e366004612d60565b612317565b34801561033e575f80fd5b5061017f61034d366004613579565b612322565b60408051600580825260c082019092525f91816020015b610371612ce0565b8152602001906001900390816103695790505090506103a15f60065f60405180602001604052805f81525061237c565b815f815181106103b3576103b36135b7565b60200260200101819052506103d860015f60405180602001604052805f8152506123b3565b816001815181106103eb576103eb6135b7565b602002602001018190525061041060025f60405180602001604052805f8152506123b3565b81600281518110610423576104236135b7565b602002602001018190525061044860045f60405180602001604052805f8152506123b3565b8160038151811061045b5761045b6135b7565b602002602001018190525061048060035f60405180602001604052805f8152506123b3565b81600481518110610493576104936135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f604051806101200160405280600280546104e8906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610514906135cb565b801561055f5780601f106105365761010080835404028352916020019161055f565b820191905f5260205f20905b81548152906001019060200180831161054257829003601f168201915b5050505050815260200160038054610576906135cb565b80601f01602080910402602001604051908101604052809291908181526020018280546105a2906135cb565b80156105ed5780601f106105c4576101008083540402835291602001916105ed565b820191905f5260205f20905b8154815290600101906020018083116105d057829003601f168201915b50505050508152602001866001600160a01b0316815260200160048054610613906135cb565b80601f016020809104026020016040519081016040528092919081815260200182805461063f906135cb565b801561068a5780601f106106615761010080835404028352916020019161068a565b820191905f5260205f20905b81548152906001019060200180831161066d57829003601f168201915b5050509183525050600160208201819052600554600160401b810460070b6040840152600160a01b900460ff16151560608301526080820186905260a09091018490529091505f9060405190808252806020026020018201604052801561072957816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816106f05790505b506040805160a081018252600181526001600160a01b0380891660208301525f9282018390526060820183905289166080820152825192935091839190610772576107726135b7565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816107935790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b8152602001876001600160a01b031681526020015f15158152602001886001600160a01b0316815250815f81518110610834576108346135b7565b60200260200101819052505f8061084c8585856123e8565b90925090506016821461085d575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b5f6108af8383612508565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146108f9575f80fd5b92915050565b5f61090a83836125e6565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161093d91815260200190565b60405180910390a1601681146108f9575f80fd5b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109cf9190613603565b5f604051808303815f865af19150503d805f8114610a08576040519150601f19603f3d011682016040523d82523d5f602084013e610a0d565b606091505b509150915081610a1e576015610a32565b80806020019051810190610a32919061362f565b60030b979650505050505050565b5f61090a8383612610565b60408051600580825260c082019092525f91816020015b610a6a612ce0565b815260200190600190039081610a62579050509050610a9a5f60065f60405180602001604052805f81525061237c565b815f81518110610aac57610aac6135b7565b6020026020010181905250610ad160015f60405180602001604052805f8152506123b3565b81600181518110610ae457610ae46135b7565b6020026020010181905250610b0960025f60405180602001604052805f8152506123b3565b81600281518110610b1c57610b1c6135b7565b6020026020010181905250610b4160035f60405180602001604052805f8152506123b3565b81600381518110610b5457610b546135b7565b6020026020010181905250610b7960045f60405180602001604052805f8152506123b3565b81600481518110610b8c57610b8c6135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054610be1906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0d906135cb565b8015610c585780601f10610c2f57610100808354040283529160200191610c58565b820191905f5260205f20905b815481529060010190602001808311610c3b57829003601f168201915b5050505050815260200160038054610c6f906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9b906135cb565b8015610ce65780601f10610cbd57610100808354040283529160200191610ce6565b820191905f5260205f20905b815481529060010190602001808311610cc957829003601f168201915b50505050508152602001856001600160a01b0316815260200160048054610d0c906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610d38906135cb565b8015610d835780601f10610d5a57610100808354040283529160200191610d83565b820191905f5260205f20905b815481529060010190602001808311610d6657829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f918291610de691859181900b90600160801b900460030b61263a565b909250905060168214610df7575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b5f806060610e4a8686866126a3565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610e91575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610ec2929190613648565b60405180910390a1610eef863033845f81518110610ee257610ee26135b7565b602002602001015161279a565b5093509350939050565b5f60605f806101676001600160a01b031663618dc65e60e01b8787604051602401610f25929190613663565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f639190613603565b5f604051808303815f865af19150503d805f8114610f9c576040519150601f19603f3d011682016040523d82523d5f602084013e610fa1565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc8282604051610fd7929190613684565b60405180910390a181610ffa57601560405180602001604052805f815250610ffe565b6016815b60039190910b97909650945050505050565b604051638f74a17b60e01b81525f903090638f74a17b9034906110399088908890600401613663565b60206040518083038185885af1158015611055573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061107a919061369e565b60405163f4a01e5b60e01b81523360048201526001600160a01b0382166024820152909150309063f4a01e5b906044016020604051808303815f875af11580156110c6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110ea91906136b9565b506040516307e9300f60e11b81526001600160a01b03821660048201523360248201523090630fd2601e906044016020604051808303815f875af1158015611134573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115891906136d0565b50611165813033856127e1565b5050505050565b6040805160018082528183019092525f91816020015b61118a612ce0565b8152602001906001900390816111825790505090506111b95f805f60405180602001604052805f81525061237c565b815f815181106111cb576111cb6135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611220906135cb565b80601f016020809104026020016040519081016040528092919081815260200182805461124c906135cb565b80156112975780601f1061126e57610100808354040283529160200191611297565b820191905f5260205f20905b81548152906001019060200180831161127a57829003601f168201915b50505050508152602001600380546112ae906135cb565b80601f01602080910402602001604051908101604052809291908181526020018280546112da906135cb565b80156113255780601f106112fc57610100808354040283529160200191611325565b820191905f5260205f20905b81548152906001019060200180831161130857829003601f168201915b50505050508152602001866001600160a01b031681526020016004805461134b906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611377906135cb565b80156113c25780601f10611399576101008083540402835291602001916113c2565b820191905f5260205f20905b8154815290600101906020018083116113a557829003601f168201915b5050509183525050600160208201819052600554600160401b900460070b6040808401919091525f606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816114165750506040805160a081018252600181526001600160a01b0388811660208301525f9282018390526060820183905289166080820152825192935091839190611496576114966135b7565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816114b75750506040805160c0810182526004815260056020820152600a91810191909152601e60608201525f608082018190526001600160a01b038a1660a083015282519293509091839190611548576115486135b7565b60209081029190910101526005545f908190611577908690600781900b90600160801b900460030b8787612828565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa826040516115ac91815260200190565b60405180910390a16016821461085d575f80fd5b60408051600580825260c082019092525f91829190816020015b6115e2612ce0565b8152602001906001900390816115da5790505090506116055f600660038661237c565b815f81518110611617576116176135b7565b602002602001018190525061162f60016003856123b3565b81600181518110611642576116426135b7565b602002602001018190525061165a60026003856123b3565b8160028151811061166d5761166d6135b7565b602002602001018190525061168560046003856123b3565b81600381518110611698576116986135b7565b60200260200101819052506116af600380856123b3565b816004815181106116c2576116c26135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001866001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611717906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611743906135cb565b801561178e5780601f106117655761010080835404028352916020019161178e565b820191905f5260205f20905b81548152906001019060200180831161177157829003601f168201915b50505050508152602001600380546117a5906135cb565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906135cb565b801561181c5780601f106117f35761010080835404028352916020019161181c565b820191905f5260205f20905b8154815290600101906020018083116117ff57829003601f168201915b50505050508152602001876001600160a01b0316815260200160048054611842906135cb565b80601f016020809104026020016040519081016040528092919081815260200182805461186e906135cb565b80156118b95780601f10611890576101008083540402835291602001916118b9565b820191905f5260205f20905b81548152906001019060200180831161189c57829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f91829161191c91859181900b90600160801b900460030b61263a565b90925090506016821461192d575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1979650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610991565b60408051600580825260c082019092525f91816020015b6119d7612ce0565b8152602001906001900390816119cf5790505090506119fa5f600660038561237c565b815f81518110611a0c57611a0c6135b7565b6020026020010181905250611a2460016003846123b3565b81600181518110611a3757611a376135b7565b6020026020010181905250611a4f60026003846123b3565b81600281518110611a6257611a626135b7565b6020026020010181905250611a7a60046003846123b3565b81600381518110611a8d57611a8d6135b7565b6020026020010181905250611aa4600380846123b3565b81600481518110611ab757611ab76135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611b0c906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611b38906135cb565b8015611b835780601f10611b5a57610100808354040283529160200191611b83565b820191905f5260205f20905b815481529060010190602001808311611b6657829003601f168201915b5050505050815260200160038054611b9a906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc6906135cb565b8015611c115780601f10611be857610100808354040283529160200191611c11565b820191905f5260205f20905b815481529060010190602001808311611bf457829003601f168201915b50505050508152602001866001600160a01b0316815260200160048054611c37906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611c63906135cb565b8015611cae5780601f10611c8557610100808354040283529160200191611cae565b820191905f5260205f20905b815481529060010190602001808311611c9157829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80611cfa8361294e565b909250905060168214611d0b575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050565b60408051600480825260a082019092525f91816020015b611d6f612ce0565b815260200190600190039081611d67579050509050611d925f600660038561237c565b815f81518110611da457611da46135b7565b6020026020010181905250611dbc60026003846123b3565b81600181518110611dcf57611dcf6135b7565b6020026020010181905250611de760046003846123b3565b81600281518110611dfa57611dfa6135b7565b6020026020010181905250611e11600380846123b3565b81600381518110611ab757611ab76135b7565b60408051600580825260c082019092525f91816020015b611e43612ce0565b815260200190600190039081611e3b579050509050611e735f60065f60405180602001604052805f81525061237c565b815f81518110611e8557611e856135b7565b6020026020010181905250611eaa60015f60405180602001604052805f8152506123b3565b81600181518110611ebd57611ebd6135b7565b6020026020010181905250611ee260025f60405180602001604052805f8152506123b3565b81600281518110611ef557611ef56135b7565b6020026020010181905250611f1a60045f60405180602001604052805f8152506123b3565b81600381518110611f2d57611f2d6135b7565b6020026020010181905250611f5260035f60405180602001604052805f8152506123b3565b81600481518110611f6557611f656135b7565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611fba906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054611fe6906135cb565b80156120315780601f1061200857610100808354040283529160200191612031565b820191905f5260205f20905b81548152906001019060200180831161201457829003601f168201915b5050505050815260200160038054612048906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054612074906135cb565b80156120bf5780601f10612096576101008083540402835291602001916120bf565b820191905f5260205f20905b8154815290600101906020018083116120a257829003601f168201915b50505050508152602001856001600160a01b03168152602001600480546120e5906135cb565b80601f0160208091040260200160405190810160405280929190818152602001828054612111906135cb565b801561215c5780601f106121335761010080835404028352916020019161215c565b820191905f5260205f20905b81548152906001019060200180831161213f57829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80610de68361294e565b5f8060606121b78686866126a3565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1601683146121fe575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d828260405161222f929190613648565b60405180910390a193509350939050565b60408051600480825260a082019092525f91829190816020015b612262612ce0565b81526020019060019003908161225a5790505090506122855f600660038661237c565b815f81518110612297576122976135b7565b60200260200101819052506122af60026003856123b3565b816001815181106122c2576122c26135b7565b60200260200101819052506122da60046003856123b3565b816002815181106122ed576122ed6135b7565b6020026020010181905250612304600380856123b3565b816003815181106116c2576116c26135b7565b5f61090a8383612a56565b5f61232e848484612a8b565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161236191815260200190565b60405180910390a160168114612375575f80fd5b9392505050565b612384612ce0565b60405180604001604052806123998787612b5f565b81526020016123a88585612b99565b905295945050505050565b6123bb612ce0565b60405180604001604052806123cf86612ca4565b81526020016123de8585612b99565b9052949350505050565b5f80848061010001515f015160070b5f14801561240f57506101008101516040015160070b155b15612425576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a6040516024016124519392919061391d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161248f9190613603565b5f6040518083038185875af1925050503d805f81146124c9576040519150601f19603f3d011682016040523d82523d5f602084013e6124ce565b606091505b5091509150816124e05760155f6124f4565b808060200190518101906124f491906139d4565b60039190910b999098509650505050505050565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516125779190613603565b5f604051808303815f865af19150503d805f81146125b0576040519150601f19603f3d011682016040523d82523d5f602084013e6125b5565b606091505b5091509150816125c65760156125da565b808060200190518101906125da919061362f565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b86866040516024016125399291906139fe565b5f805f6101676001600160a01b0316637d305cfa60e01b8686604051602401612539929190613a59565b5f80848061010001515f015160070b5f14801561266157506101008101516040015160070b155b15612677576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a60405160240161245193929190613a7a565b5f8060605f806101676001600160a01b031663e0f4059a60e01b8989896040516024016126d293929190613aa8565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516127109190613603565b5f604051808303815f865af19150503d805f8114612749576040519150601f19603f3d011682016040523d82523d5f602084013e61274e565b606091505b50915091508161277057604080515f8082526020820190925260159190612784565b808060200190518101906127849190613b25565b60039290920b9a90995090975095505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610991565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610991565b5f80868061010001515f015160070b5f14801561284f57506101008101516040015160070b155b15612865576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c604051602401612895959493929190613bdf565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516128d39190613603565b5f6040518083038185875af1925050503d805f811461290d576040519150601f19603f3d011682016040523d82523d5f602084013e612912565b606091505b5091509150816129245760155f612938565b8080602001905181019061293891906139d4565b60039190910b9b909a5098505050505050505050565b5f80828061010001515f015160070b5f14801561297557506101008101516040015160070b155b1561298b576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b886040516024016129b39190613caa565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516129f19190613603565b5f6040518083038185875af1925050503d805f8114612a2b576040519150601f19603f3d011682016040523d82523d5f602084013e612a30565b606091505b509150915081612a425760155f610ffe565b80806020019051810190610ffe91906139d4565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b90606401612539565b604080516001600160a01b03858116602483015284166044820152606480820184905282518083039091018152608490910182526020810180516001600160e01b031663e1f21c6760e01b17905290515f918291829161016791612aef9190613603565b5f604051808303815f865af19150503d805f8114612b28576040519150601f19603f3d011682016040523d82523d5f602084013e612b2d565b606091505b509150915081612b3e576015612b52565b80806020019051810190612b52919061362f565b60030b9695505050505050565b5f612b82836006811115612b7557612b75613cbc565b600160ff9091161b821790565b9050612375826006811115612b7557612b75613cbc565b612bdc6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b5f836004811115612bef57612bef613cbc565b03612bfd57600181526108f9565b6001836004811115612c1157612c11613cbc565b03612c2b575f546001600160a01b031660208201526108f9565b6002836004811115612c3f57612c3f613cbc565b03612c5057604081018290526108f9565b6003836004811115612c6457612c64613cbc565b03612c7557606081018290526108f9565b6004836004811115612c8957612c89613cbc565b036108f9575f546001600160a01b0316608082015292915050565b5f60015f836006811115612cba57612cba613cbc565b6006811115612ccb57612ccb613cbc565b81526020019081526020015f20549050919050565b60405180604001604052805f8152602001612d346040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b905290565b6001600160a01b0381168114612d4d575f80fd5b50565b8035612d5b81612d39565b919050565b5f8060408385031215612d71575f80fd5b8235612d7c81612d39565b91506020830135612d8c81612d39565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715612dce57612dce612d97565b60405290565b60405160a0810167ffffffffffffffff81118282101715612dce57612dce612d97565b604051610120810167ffffffffffffffff81118282101715612dce57612dce612d97565b604051601f8201601f1916810167ffffffffffffffff81118282101715612e4457612e44612d97565b604052919050565b5f67ffffffffffffffff821115612e6557612e65612d97565b5060051b60200190565b5f8060408385031215612e80575f80fd5b8235612e8b81612d39565b915060208381013567ffffffffffffffff811115612ea7575f80fd5b8401601f81018613612eb7575f80fd5b8035612eca612ec582612e4c565b612e1b565b81815260059190911b82018301908381019088831115612ee8575f80fd5b928401925b82841015612f0f578335612f0081612d39565b82529284019290840190612eed565b80955050505050509250929050565b5f805f8060808587031215612f31575f80fd5b8435612f3c81612d39565b93506020850135612f4c81612d39565b92506040850135612f5c81612d39565b9396929550929360600135925050565b5f82601f830112612f7b575f80fd5b813567ffffffffffffffff811115612f9557612f95612d97565b612fa8601f8201601f1916602001612e1b565b818152846020838601011115612fbc575f80fd5b816020850160208301375f918101602001919091529392505050565b80358015158114612d5b575f80fd5b8060070b8114612d4d575f80fd5b8035612d5b81612fe7565b5f82601f83011261300f575f80fd5b8135602061301f612ec583612e4c565b82815260059290921b8401810191818101908684111561303d575f80fd5b8286015b8481101561314e57803567ffffffffffffffff80821115613060575f80fd5b908801906040601f19838c038101821315613079575f80fd5b613081612dab565b8885013581528285013584811115613097575f80fd5b949094019360a0858e03830112156130ad575f80fd5b6130b5612dd4565b91506130c2898601612fd8565b8252828501356130d181612d39565b828a0152606085810135858111156130e7575f80fd5b6130f58f8c838a0101612f6c565b858501525060809350838601358581111561310e575f80fd5b61311c8f8c838a0101612f6c565b82850152505060a0850135945061313285612d39565b9181019390935280870192909252508352918301918301613041565b509695505050505050565b5f60608284031215613169575f80fd5b6040516060810181811067ffffffffffffffff8211171561318c5761318c612d97565b604052905080823561319d81612fe7565b815260208301356131ad81612d39565b602082015260408301356131c081612fe7565b6040919091015292915050565b5f80604083850312156131de575f80fd5b82356131e981612d39565b9150602083013567ffffffffffffffff80821115613205575f80fd5b908401906101608287031215613219575f80fd5b613221612df7565b82358281111561322f575f80fd5b61323b88828601612f6c565b82525060208301358281111561324f575f80fd5b61325b88828601612f6c565b60208301525061326d60408401612d50565b6040820152606083013582811115613283575f80fd5b61328f88828601612f6c565b6060830152506132a160808401612fd8565b60808201526132b260a08401612ff5565b60a08201526132c360c08401612fd8565b60c082015260e0830135828111156132d9575f80fd5b6132e588828601613000565b60e08301525061010091506132fc87838501613159565b828201528093505050509250929050565b5f6020828403121561331d575f80fd5b813561237581612d39565b5f805f6060848603121561333a575f80fd5b833561334581612d39565b925060208481013561335681612fe7565b9250604085013567ffffffffffffffff80821115613372575f80fd5b818701915087601f830112613385575f80fd5b8135613393612ec582612e4c565b81815260059190911b8301840190848101908a8311156133b1575f80fd5b8585015b838110156133e7578035858111156133cb575f80fd5b6133d98d89838a0101612f6c565b8452509186019186016133b5565b508096505050505050509250925092565b5f815180845260208085019450602084015f5b8381101561342a57815160070b8752958201959082019060010161340b565b509495945050505050565b8381528260070b6020820152606060408201525f61345660608301846133f8565b95945050505050565b5f8060408385031215613470575f80fd5b823561347b81612d39565b9150602083013567ffffffffffffffff811115613496575f80fd5b6134a285828601612f6c565b9150509250929050565b5f5b838110156134c65781810151838201526020016134ae565b50505f910152565b5f81518084526134e58160208601602086016134ac565b601f01601f19169290920160200192915050565b828152604060208201525f61351160408301846134ce565b949350505050565b5f805f6060848603121561352b575f80fd5b833561353681612d39565b9250602084013567ffffffffffffffff811115613551575f80fd5b61355d86828701612f6c565b925050604084013561356e81612fe7565b809150509250925092565b5f805f6060848603121561358b575f80fd5b833561359681612d39565b925060208401356135a681612d39565b929592945050506040919091013590565b634e487b7160e01b5f52603260045260245ffd5b600181811c908216806135df57607f821691505b6020821081036135fd57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f82516136148184602087016134ac565b9190910192915050565b8051600381900b8114612d5b575f80fd5b5f6020828403121561363f575f80fd5b6123758261361e565b8260070b8152604060208201525f61351160408301846133f8565b6001600160a01b0383168152604060208201525f61351160408301846134ce565b8215158152604060208201525f61351160408301846134ce565b5f602082840312156136ae575f80fd5b815161237581612d39565b5f602082840312156136c9575f80fd5b5051919050565b5f602082840312156136e0575f80fd5b815161237581612fe7565b5f82825180855260208086019550808260051b8401018186015f5b848110156137a357601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a015261376560e08a01866134ce565b92860151898403603f1901858b015292945061378185846134ce565b9501511660c09790970196909652505098840198925090830190600101613706565b5090979650505050505050565b5f61016082518185526137c5828601826134ce565b915050602083015184820360208601526137df82826134ce565b91505060408301516137fc60408601826001600160a01b03169052565b506060830151848203606086015261381482826134ce565b915050608083015161382a608086018215159052565b5060a083015161383f60a086018260070b9052565b5060c083015161385360c086018215159052565b5060e083015184820360e086015261386b82826136eb565b915050610100808401516138a782870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b8381101561342a578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a090960195908201906001016138c4565b5f606080835261393060608401876137b0565b60208482038186015261394382886138b1565b915060408583036040870152828751808552838501915083890194505f5b818110156139c45785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c090920191600101613961565b50909a9950505050505050505050565b5f80604083850312156139e5575f80fd5b6139ee8361361e565b91506020830151612d8c81612d39565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015613a4b578551851683529483019491830191600101613a2d565b509098975050505050505050565b6001600160a01b0383168152604060208201525f61351160408301846137b0565b606081525f613a8c60608301866137b0565b90508360070b60208301528260030b6040830152949350505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b82811015613b1657607f19888703018452613b048683516134ce565b95509284019290840190600101613ae8565b50939998505050505050505050565b5f805f60608486031215613b37575f80fd5b613b408461361e565b9250602080850151613b5181612fe7565b604086015190935067ffffffffffffffff811115613b6d575f80fd5b8501601f81018713613b7d575f80fd5b8051613b8b612ec582612e4c565b81815260059190911b82018301908381019089831115613ba9575f80fd5b928401925b82841015613bd0578351613bc181612fe7565b82529284019290840190613bae565b80955050505050509250925092565b5f60a0808352613bf260a08401896137b0565b602060078960070b8287015260408960030b604088015260608785036060890152613c1d858b6138b1565b9450608088860360808a0152858a518088528688019150868c0197505f5b81811015613c955788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c090920191600101613c3b565b50909f9e505050505050505050505050505050565b602081525f61237560208301846137b0565b634e487b7160e01b5f52602160045260245ffdfea2646970667358221220575ca66fd032e49d40288cfcf0d06ab70232ab6ff9612ebd0dfeff08ba75b28664736f6c63430008180033", + "bytecode": "0x60c06040526009608090815268746f6b656e4e616d6560b81b60a0526002906200002a90826200025d565b5060408051808201909152600b81526a1d1bdad95b94de5b589bdb60aa1b60208201526003906200005c90826200025d565b50604080518082019091526004808252636d656d6f60e01b6020830152906200008690826200025d565b50600580546001600160a81b0319166c04a817c80000000002540be400179055348015620000b2575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a5562000329565b634e487b7160e01b5f52604160045260245ffd5b600181811c90821680620001e857607f821691505b6020821081036200020757634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156200025857805f5260205f20601f840160051c81016020851015620002345750805b601f840160051c820191505b8181101562000255575f815560010162000240565b50505b505050565b81516001600160401b03811115620002795762000279620001bf565b62000291816200028a8454620001d3565b846200020d565b602080601f831160018114620002c7575f8415620002af5750858301515b5f19600386901b1c1916600185901b17855562000321565b5f85815260208120601f198616915b82811015620002f757888601518255948401946001909101908401620002d6565b50858210156200031557878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b613d9480620003375f395ff3fe608060405260043610610110575f3560e01c80638ba74da01161009d578063d85f74c111610062578063d85f74c1146102cf578063de84a779146102e2578063e9f7322614610301578063f4a01e5b14610314578063f848fec414610333575f80fd5b80638ba74da01461024c5780638f74a17b1461025f5780639b23d3d91461028a578063b35d417a146102a9578063cc265af4146102bc575f80fd5b806336348de3116100e357806336348de3146101ac5780634b5c6687146101cb5780634d1769d6146101de578063618dc65e1461020c57806371de370714610239575f80fd5b80630488c939146101145780630fd2601e14610129578063118741e71461016057806315dacbea1461018d575b5f80fd5b610127610122366004612dee565b610352565b005b348015610134575f80fd5b50610148610143366004612dee565b6108a4565b60405160079190910b81526020015b60405180910390f35b34801561016b575f80fd5b5061017f61017a366004612efd565b6108ff565b604051908152602001610157565b348015610198575f80fd5b506101486101a7366004612fac565b610951565b3480156101b7575f80fd5b5061017f6101c636600461325b565b610a40565b6101276101d936600461339b565b610a4b565b3480156101e9575f80fd5b506101fd6101f83660046133b6565b610e73565b604051610157939291906134c3565b348015610217575f80fd5b5061022b6102263660046134ed565b610f31565b604051610157929190613587565b6101276102473660046135a7565b611048565b61012761025a366004612dee565b6111a4565b61027261026d3660046134ed565b6115f8565b6040516001600160a01b039091168152602001610157565b348015610295575f80fd5b506101486102a4366004612fac565b6119d7565b6101276102b73660046134ed565b611a1b565b6101276102ca3660046134ed565b611dde565b6101276102dd36600461339b565b611eb2565b3480156102ed575f80fd5b506101fd6102fc3660046133b6565b612236565b61027261030f3660046134ed565b6122ce565b34801561031f575f80fd5b5061017f61032e366004612dee565b6123a5565b34801561033e575f80fd5b5061017f61034d366004613607565b6123b0565b60408051600580825260c082019092525f91816020015b610371612d6e565b8152602001906001900390816103695790505090506103a15f60065f60405180602001604052805f81525061240a565b815f815181106103b3576103b3613645565b60200260200101819052506103d860015f60405180602001604052805f815250612441565b816001815181106103eb576103eb613645565b602002602001018190525061041060025f60405180602001604052805f815250612441565b8160028151811061042357610423613645565b602002602001018190525061044860045f60405180602001604052805f815250612441565b8160038151811061045b5761045b613645565b602002602001018190525061048060035f60405180602001604052805f815250612441565b8160048151811061049357610493613645565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f604051806101200160405280600280546104e890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461051490613659565b801561055f5780601f106105365761010080835404028352916020019161055f565b820191905f5260205f20905b81548152906001019060200180831161054257829003601f168201915b505050505081526020016003805461057690613659565b80601f01602080910402602001604051908101604052809291908181526020018280546105a290613659565b80156105ed5780601f106105c4576101008083540402835291602001916105ed565b820191905f5260205f20905b8154815290600101906020018083116105d057829003601f168201915b50505050508152602001866001600160a01b031681526020016004805461061390613659565b80601f016020809104026020016040519081016040528092919081815260200182805461063f90613659565b801561068a5780601f106106615761010080835404028352916020019161068a565b820191905f5260205f20905b81548152906001019060200180831161066d57829003601f168201915b5050509183525050600160208201819052600554600160401b810460070b6040840152600160a01b900460ff16151560608301526080820186905260a09091018490529091505f9060405190808252806020026020018201604052801561072957816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816106f05790505b506040805160a081018252600181526001600160a01b0380891660208301525f928201839052606082018390528916608082015282519293509183919061077257610772613645565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816107935790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b8152602001876001600160a01b031681526020015f15158152602001886001600160a01b0316815250815f8151811061083457610834613645565b60200260200101819052505f8061084c858585612476565b90925090506016821461085d575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b5f6108af8383612596565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146108f9575f80fd5b92915050565b5f61090a8383612674565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161093d91815260200190565b60405180910390a1601681146108f9575f80fd5b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109cf9190613691565b5f604051808303815f865af19150503d805f8114610a08576040519150601f19603f3d011682016040523d82523d5f602084013e610a0d565b606091505b509150915081610a1e576015610a32565b80806020019051810190610a3291906136bd565b60030b979650505050505050565b5f61090a838361269e565b60408051600680825260e082019092525f91816020015b610a6a612d6e565b815260200190600190039081610a62579050509050610a9a5f60065f60405180602001604052805f81525061240a565b815f81518110610aac57610aac613645565b6020026020010181905250610ad160015f60405180602001604052805f815250612441565b81600181518110610ae457610ae4613645565b6020026020010181905250610b0960025f60405180602001604052805f815250612441565b81600281518110610b1c57610b1c613645565b6020026020010181905250610b4160035f60405180602001604052805f815250612441565b81600381518110610b5457610b54613645565b6020026020010181905250610b7960045f60405180602001604052805f815250612441565b81600481518110610b8c57610b8c613645565b6020026020010181905250610bb160055f60405180602001604052805f815250612441565b81600581518110610bc457610bc4613645565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054610c1990613659565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4590613659565b8015610c905780601f10610c6757610100808354040283529160200191610c90565b820191905f5260205f20905b815481529060010190602001808311610c7357829003601f168201915b5050505050815260200160038054610ca790613659565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd390613659565b8015610d1e5780601f10610cf557610100808354040283529160200191610d1e565b820191905f5260205f20905b815481529060010190602001808311610d0157829003601f168201915b50505050508152602001856001600160a01b0316815260200160048054610d4490613659565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7090613659565b8015610dbb5780601f10610d9257610100808354040283529160200191610dbb565b820191905f5260205f20905b815481529060010190602001808311610d9e57829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f918291610e1e91859181900b90600160801b900460030b6126c8565b909250905060168214610e2f575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b5f806060610e82868686612731565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610ec9575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610efa9291906136d6565b60405180910390a1610f27863033845f81518110610f1a57610f1a613645565b6020026020010151612828565b5093509350939050565b5f60605f806101676001600160a01b031663618dc65e60e01b8787604051602401610f5d9291906136f1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f9b9190613691565b5f604051808303815f865af19150503d805f8114610fd4576040519150601f19603f3d011682016040523d82523d5f602084013e610fd9565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161100f929190613712565b60405180910390a18161103257601560405180602001604052805f815250611036565b6016815b60039190910b97909650945050505050565b604051638f74a17b60e01b81525f903090638f74a17b90349061107190889088906004016136f1565b60206040518083038185885af115801561108d573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906110b2919061372c565b60405163f4a01e5b60e01b81523360048201526001600160a01b0382166024820152909150309063f4a01e5b906044016020604051808303815f875af11580156110fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111229190613747565b506040516307e9300f60e11b81526001600160a01b03821660048201523360248201523090630fd2601e906044016020604051808303815f875af115801561116c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611190919061375e565b5061119d8130338561286f565b5050505050565b6040805160018082528183019092525f91816020015b6111c2612d6e565b8152602001906001900390816111ba5790505090506111f15f805f60405180602001604052805f81525061240a565b815f8151811061120357611203613645565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f6040518061012001604052806002805461125890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461128490613659565b80156112cf5780601f106112a6576101008083540402835291602001916112cf565b820191905f5260205f20905b8154815290600101906020018083116112b257829003601f168201915b50505050508152602001600380546112e690613659565b80601f016020809104026020016040519081016040528092919081815260200182805461131290613659565b801561135d5780601f106113345761010080835404028352916020019161135d565b820191905f5260205f20905b81548152906001019060200180831161134057829003601f168201915b50505050508152602001866001600160a01b031681526020016004805461138390613659565b80601f01602080910402602001604051908101604052809291908181526020018280546113af90613659565b80156113fa5780601f106113d1576101008083540402835291602001916113fa565b820191905f5260205f20905b8154815290600101906020018083116113dd57829003601f168201915b5050509183525050600160208201819052600554600160401b900460070b6040808401919091525f606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f1990920191018161144e5750506040805160a081018252606481526001600160a01b0388811660208301525f92820183905260608201839052891660808201528251929350918391906114ce576114ce613645565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816114ef5750506040805160c0810182526004815260056020820152600a91810191909152601e60608201525f608082018190526001600160a01b038a1660a08301528251929350909183919061158057611580613645565b60209081029190910101526005545f9081906115af908690600781900b90600160801b900460030b87876128b6565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa826040516115e491815260200190565b60405180910390a16016821461085d575f80fd5b60408051600680825260e082019092525f91829190816020015b61161a612d6e565b81526020019060019003908161161257905050905061163d5f600660038661240a565b815f8151811061164f5761164f613645565b60200260200101819052506116676001600385612441565b8160018151811061167a5761167a613645565b60200260200101819052506116926002600385612441565b816002815181106116a5576116a5613645565b60200260200101819052506116bd6004600385612441565b816003815181106116d0576116d0613645565b60200260200101819052506116e760038085612441565b816004815181106116fa576116fa613645565b60200260200101819052506117126005600385612441565b8160058151811061172557611725613645565b60200260200101819052505f60405180606001604052805f60070b8152602001866001600160a01b03168152602001627a120060070b81525090505f6040518061012001604052806002805461177a90613659565b80601f01602080910402602001604051908101604052809291908181526020018280546117a690613659565b80156117f15780601f106117c8576101008083540402835291602001916117f1565b820191905f5260205f20905b8154815290600101906020018083116117d457829003601f168201915b505050505081526020016003805461180890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461183490613659565b801561187f5780601f106118565761010080835404028352916020019161187f565b820191905f5260205f20905b81548152906001019060200180831161186257829003601f168201915b50505050508152602001876001600160a01b03168152602001600480546118a590613659565b80601f01602080910402602001604051908101604052809291908181526020018280546118d190613659565b801561191c5780601f106118f35761010080835404028352916020019161191c565b820191905f5260205f20905b8154815290600101906020018083116118ff57829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f91829161197f91859181900b90600160801b900460030b6126c8565b909250905060168214611990575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1979650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610991565b60408051600680825260e082019092525f91816020015b611a3a612d6e565b815260200190600190039081611a32579050509050611a5d5f600660038561240a565b815f81518110611a6f57611a6f613645565b6020026020010181905250611a876001600384612441565b81600181518110611a9a57611a9a613645565b6020026020010181905250611ab26002600384612441565b81600281518110611ac557611ac5613645565b6020026020010181905250611add6004600384612441565b81600381518110611af057611af0613645565b6020026020010181905250611b0760038084612441565b81600481518110611b1a57611b1a613645565b6020026020010181905250611b326005600384612441565b81600581518110611b4557611b45613645565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611b9a90613659565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc690613659565b8015611c115780601f10611be857610100808354040283529160200191611c11565b820191905f5260205f20905b815481529060010190602001808311611bf457829003601f168201915b5050505050815260200160038054611c2890613659565b80601f0160208091040260200160405190810160405280929190818152602001828054611c5490613659565b8015611c9f5780601f10611c7657610100808354040283529160200191611c9f565b820191905f5260205f20905b815481529060010190602001808311611c8257829003601f168201915b50505050508152602001866001600160a01b0316815260200160048054611cc590613659565b80601f0160208091040260200160405190810160405280929190818152602001828054611cf190613659565b8015611d3c5780601f10611d1357610100808354040283529160200191611d3c565b820191905f5260205f20905b815481529060010190602001808311611d1f57829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80611d88836129dc565b909250905060168214611d99575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050565b60408051600480825260a082019092525f91816020015b611dfd612d6e565b815260200190600190039081611df5579050509050611e205f600660038561240a565b815f81518110611e3257611e32613645565b6020026020010181905250611e4a6002600384612441565b81600181518110611e5d57611e5d613645565b6020026020010181905250611e756004600384612441565b81600281518110611e8857611e88613645565b6020026020010181905250611e9f60038084612441565b81600381518110611b4557611b45613645565b60408051600580825260c082019092525f91816020015b611ed1612d6e565b815260200190600190039081611ec9579050509050611f015f60065f60405180602001604052805f81525061240a565b815f81518110611f1357611f13613645565b6020026020010181905250611f3860015f60405180602001604052805f815250612441565b81600181518110611f4b57611f4b613645565b6020026020010181905250611f7060025f60405180602001604052805f815250612441565b81600281518110611f8357611f83613645565b6020026020010181905250611fa860045f60405180602001604052805f815250612441565b81600381518110611fbb57611fbb613645565b6020026020010181905250611fe060035f60405180602001604052805f815250612441565b81600481518110611ff357611ff3613645565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f6040518061012001604052806002805461204890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461207490613659565b80156120bf5780601f10612096576101008083540402835291602001916120bf565b820191905f5260205f20905b8154815290600101906020018083116120a257829003601f168201915b50505050508152602001600380546120d690613659565b80601f016020809104026020016040519081016040528092919081815260200182805461210290613659565b801561214d5780601f106121245761010080835404028352916020019161214d565b820191905f5260205f20905b81548152906001019060200180831161213057829003601f168201915b50505050508152602001856001600160a01b031681526020016004805461217390613659565b80601f016020809104026020016040519081016040528092919081815260200182805461219f90613659565b80156121ea5780601f106121c1576101008083540402835291602001916121ea565b820191905f5260205f20905b8154815290600101906020018083116121cd57829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80610e1e836129dc565b5f806060612245868686612731565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a16016831461228c575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d82826040516122bd9291906136d6565b60405180910390a193509350939050565b60408051600480825260a082019092525f91829190816020015b6122f0612d6e565b8152602001906001900390816122e85790505090506123135f600660038661240a565b815f8151811061232557612325613645565b602002602001018190525061233d6002600385612441565b8160018151811061235057612350613645565b60200260200101819052506123686004600385612441565b8160028151811061237b5761237b613645565b602002602001018190525061239260038085612441565b8160038151811061172557611725613645565b5f61090a8383612ae4565b5f6123bc848484612b19565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa816040516123ef91815260200190565b60405180910390a160168114612403575f80fd5b9392505050565b612412612d6e565b60405180604001604052806124278787612bed565b81526020016124368585612c27565b905295945050505050565b612449612d6e565b604051806040016040528061245d86612d32565b815260200161246c8585612c27565b9052949350505050565b5f80848061010001515f015160070b5f14801561249d57506101008101516040015160070b155b156124b3576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a6040516024016124df939291906139ab565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161251d9190613691565b5f6040518083038185875af1925050503d805f8114612557576040519150601f19603f3d011682016040523d82523d5f602084013e61255c565b606091505b50915091508161256e5760155f612582565b808060200190518101906125829190613a62565b60039190910b999098509650505050505050565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516126059190613691565b5f604051808303815f865af19150503d805f811461263e576040519150601f19603f3d011682016040523d82523d5f602084013e612643565b606091505b509150915081612654576015612668565b8080602001905181019061266891906136bd565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b86866040516024016125c7929190613a8c565b5f805f6101676001600160a01b0316637d305cfa60e01b86866040516024016125c7929190613ae7565b5f80848061010001515f015160070b5f1480156126ef57506101008101516040015160070b155b15612705576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a6040516024016124df93929190613b08565b5f8060605f806101676001600160a01b031663e0f4059a60e01b89898960405160240161276093929190613b36565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161279e9190613691565b5f604051808303815f865af19150503d805f81146127d7576040519150601f19603f3d011682016040523d82523d5f602084013e6127dc565b606091505b5091509150816127fe57604080515f8082526020820190925260159190612812565b808060200190518101906128129190613bb3565b60039290920b9a90995090975095505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610991565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610991565b5f80868061010001515f015160070b5f1480156128dd57506101008101516040015160070b155b156128f3576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c604051602401612923959493929190613c6d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516129619190613691565b5f6040518083038185875af1925050503d805f811461299b576040519150601f19603f3d011682016040523d82523d5f602084013e6129a0565b606091505b5091509150816129b25760155f6129c6565b808060200190518101906129c69190613a62565b60039190910b9b909a5098505050505050505050565b5f80828061010001515f015160070b5f148015612a0357506101008101516040015160070b155b15612a19576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b88604051602401612a419190613d38565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612a7f9190613691565b5f6040518083038185875af1925050503d805f8114612ab9576040519150601f19603f3d011682016040523d82523d5f602084013e612abe565b606091505b509150915081612ad05760155f611036565b808060200190518101906110369190613a62565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b906064016125c7565b604080516001600160a01b03858116602483015284166044820152606480820184905282518083039091018152608490910182526020810180516001600160e01b031663e1f21c6760e01b17905290515f918291829161016791612b7d9190613691565b5f604051808303815f865af19150503d805f8114612bb6576040519150601f19603f3d011682016040523d82523d5f602084013e612bbb565b606091505b509150915081612bcc576015612be0565b80806020019051810190612be091906136bd565b60030b9695505050505050565b5f612c10836006811115612c0357612c03613d4a565b600160ff9091161b821790565b9050612403826006811115612c0357612c03613d4a565b612c6a6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b5f836004811115612c7d57612c7d613d4a565b03612c8b57600181526108f9565b6001836004811115612c9f57612c9f613d4a565b03612cb9575f546001600160a01b031660208201526108f9565b6002836004811115612ccd57612ccd613d4a565b03612cde57604081018290526108f9565b6003836004811115612cf257612cf2613d4a565b03612d0357606081018290526108f9565b6004836004811115612d1757612d17613d4a565b036108f9575f546001600160a01b0316608082015292915050565b5f60015f836006811115612d4857612d48613d4a565b6006811115612d5957612d59613d4a565b81526020019081526020015f20549050919050565b60405180604001604052805f8152602001612dc26040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b905290565b6001600160a01b0381168114612ddb575f80fd5b50565b8035612de981612dc7565b919050565b5f8060408385031215612dff575f80fd5b8235612e0a81612dc7565b91506020830135612e1a81612dc7565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715612e5c57612e5c612e25565b60405290565b60405160a0810167ffffffffffffffff81118282101715612e5c57612e5c612e25565b604051610120810167ffffffffffffffff81118282101715612e5c57612e5c612e25565b604051601f8201601f1916810167ffffffffffffffff81118282101715612ed257612ed2612e25565b604052919050565b5f67ffffffffffffffff821115612ef357612ef3612e25565b5060051b60200190565b5f8060408385031215612f0e575f80fd5b8235612f1981612dc7565b915060208381013567ffffffffffffffff811115612f35575f80fd5b8401601f81018613612f45575f80fd5b8035612f58612f5382612eda565b612ea9565b81815260059190911b82018301908381019088831115612f76575f80fd5b928401925b82841015612f9d578335612f8e81612dc7565b82529284019290840190612f7b565b80955050505050509250929050565b5f805f8060808587031215612fbf575f80fd5b8435612fca81612dc7565b93506020850135612fda81612dc7565b92506040850135612fea81612dc7565b9396929550929360600135925050565b5f82601f830112613009575f80fd5b813567ffffffffffffffff81111561302357613023612e25565b613036601f8201601f1916602001612ea9565b81815284602083860101111561304a575f80fd5b816020850160208301375f918101602001919091529392505050565b80358015158114612de9575f80fd5b8060070b8114612ddb575f80fd5b8035612de981613075565b5f82601f83011261309d575f80fd5b813560206130ad612f5383612eda565b82815260059290921b840181019181810190868411156130cb575f80fd5b8286015b848110156131dc57803567ffffffffffffffff808211156130ee575f80fd5b908801906040601f19838c038101821315613107575f80fd5b61310f612e39565b8885013581528285013584811115613125575f80fd5b949094019360a0858e038301121561313b575f80fd5b613143612e62565b9150613150898601613066565b82528285013561315f81612dc7565b828a015260608581013585811115613175575f80fd5b6131838f8c838a0101612ffa565b858501525060809350838601358581111561319c575f80fd5b6131aa8f8c838a0101612ffa565b82850152505060a085013594506131c085612dc7565b91810193909352808701929092525083529183019183016130cf565b509695505050505050565b5f606082840312156131f7575f80fd5b6040516060810181811067ffffffffffffffff8211171561321a5761321a612e25565b604052905080823561322b81613075565b8152602083013561323b81612dc7565b6020820152604083013561324e81613075565b6040919091015292915050565b5f806040838503121561326c575f80fd5b823561327781612dc7565b9150602083013567ffffffffffffffff80821115613293575f80fd5b9084019061016082870312156132a7575f80fd5b6132af612e85565b8235828111156132bd575f80fd5b6132c988828601612ffa565b8252506020830135828111156132dd575f80fd5b6132e988828601612ffa565b6020830152506132fb60408401612dde565b6040820152606083013582811115613311575f80fd5b61331d88828601612ffa565b60608301525061332f60808401613066565b608082015261334060a08401613083565b60a082015261335160c08401613066565b60c082015260e083013582811115613367575f80fd5b6133738882860161308e565b60e083015250610100915061338a878385016131e7565b828201528093505050509250929050565b5f602082840312156133ab575f80fd5b813561240381612dc7565b5f805f606084860312156133c8575f80fd5b83356133d381612dc7565b92506020848101356133e481613075565b9250604085013567ffffffffffffffff80821115613400575f80fd5b818701915087601f830112613413575f80fd5b8135613421612f5382612eda565b81815260059190911b8301840190848101908a83111561343f575f80fd5b8585015b8381101561347557803585811115613459575f80fd5b6134678d89838a0101612ffa565b845250918601918601613443565b508096505050505050509250925092565b5f815180845260208085019450602084015f5b838110156134b857815160070b87529582019590820190600101613499565b509495945050505050565b8381528260070b6020820152606060408201525f6134e46060830184613486565b95945050505050565b5f80604083850312156134fe575f80fd5b823561350981612dc7565b9150602083013567ffffffffffffffff811115613524575f80fd5b61353085828601612ffa565b9150509250929050565b5f5b8381101561355457818101518382015260200161353c565b50505f910152565b5f815180845261357381602086016020860161353a565b601f01601f19169290920160200192915050565b828152604060208201525f61359f604083018461355c565b949350505050565b5f805f606084860312156135b9575f80fd5b83356135c481612dc7565b9250602084013567ffffffffffffffff8111156135df575f80fd5b6135eb86828701612ffa565b92505060408401356135fc81613075565b809150509250925092565b5f805f60608486031215613619575f80fd5b833561362481612dc7565b9250602084013561363481612dc7565b929592945050506040919091013590565b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168061366d57607f821691505b60208210810361368b57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f82516136a281846020870161353a565b9190910192915050565b8051600381900b8114612de9575f80fd5b5f602082840312156136cd575f80fd5b612403826136ac565b8260070b8152604060208201525f61359f6040830184613486565b6001600160a01b0383168152604060208201525f61359f604083018461355c565b8215158152604060208201525f61359f604083018461355c565b5f6020828403121561373c575f80fd5b815161240381612dc7565b5f60208284031215613757575f80fd5b5051919050565b5f6020828403121561376e575f80fd5b815161240381613075565b5f82825180855260208086019550808260051b8401018186015f5b8481101561383157601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a01526137f360e08a018661355c565b92860151898403603f1901858b015292945061380f858461355c565b9501511660c09790970196909652505098840198925090830190600101613794565b5090979650505050505050565b5f61016082518185526138538286018261355c565b9150506020830151848203602086015261386d828261355c565b915050604083015161388a60408601826001600160a01b03169052565b50606083015184820360608601526138a2828261355c565b91505060808301516138b8608086018215159052565b5060a08301516138cd60a086018260070b9052565b5060c08301516138e160c086018215159052565b5060e083015184820360e08601526138f98282613779565b9150506101008084015161393582870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b838110156134b8578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101613952565b5f60608083526139be606084018761383e565b6020848203818601526139d1828861393f565b915060408583036040870152828751808552838501915083890194505f5b81811015613a525785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c0909201916001016139ef565b50909a9950505050505050505050565b5f8060408385031215613a73575f80fd5b613a7c836136ac565b91506020830151612e1a81612dc7565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015613ad9578551851683529483019491830191600101613abb565b509098975050505050505050565b6001600160a01b0383168152604060208201525f61359f604083018461383e565b606081525f613b1a606083018661383e565b90508360070b60208301528260030b6040830152949350505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b82811015613ba457607f19888703018452613b9286835161355c565b95509284019290840190600101613b76565b50939998505050505050505050565b5f805f60608486031215613bc5575f80fd5b613bce846136ac565b9250602080850151613bdf81613075565b604086015190935067ffffffffffffffff811115613bfb575f80fd5b8501601f81018713613c0b575f80fd5b8051613c19612f5382612eda565b81815260059190911b82018301908381019089831115613c37575f80fd5b928401925b82841015613c5e578351613c4f81613075565b82529284019290840190613c3c565b80955050505050509250925092565b5f60a0808352613c8060a084018961383e565b602060078960070b8287015260408960030b604088015260608785036060890152613cab858b61393f565b9450608088860360808a0152858a518088528688019150868c0197505f5b81811015613d235788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c090920191600101613cc9565b50909f9e505050505050505050505050505050565b602081525f612403602083018461383e565b634e487b7160e01b5f52602160045260245ffdfea2646970667358221220ff1f32f09b2f502361a23acdef2eeef747b3329dc66049e880f3ad4bdcc9203b64736f6c63430008180033", + "deployedBytecode": "0x608060405260043610610110575f3560e01c80638ba74da01161009d578063d85f74c111610062578063d85f74c1146102cf578063de84a779146102e2578063e9f7322614610301578063f4a01e5b14610314578063f848fec414610333575f80fd5b80638ba74da01461024c5780638f74a17b1461025f5780639b23d3d91461028a578063b35d417a146102a9578063cc265af4146102bc575f80fd5b806336348de3116100e357806336348de3146101ac5780634b5c6687146101cb5780634d1769d6146101de578063618dc65e1461020c57806371de370714610239575f80fd5b80630488c939146101145780630fd2601e14610129578063118741e71461016057806315dacbea1461018d575b5f80fd5b610127610122366004612dee565b610352565b005b348015610134575f80fd5b50610148610143366004612dee565b6108a4565b60405160079190910b81526020015b60405180910390f35b34801561016b575f80fd5b5061017f61017a366004612efd565b6108ff565b604051908152602001610157565b348015610198575f80fd5b506101486101a7366004612fac565b610951565b3480156101b7575f80fd5b5061017f6101c636600461325b565b610a40565b6101276101d936600461339b565b610a4b565b3480156101e9575f80fd5b506101fd6101f83660046133b6565b610e73565b604051610157939291906134c3565b348015610217575f80fd5b5061022b6102263660046134ed565b610f31565b604051610157929190613587565b6101276102473660046135a7565b611048565b61012761025a366004612dee565b6111a4565b61027261026d3660046134ed565b6115f8565b6040516001600160a01b039091168152602001610157565b348015610295575f80fd5b506101486102a4366004612fac565b6119d7565b6101276102b73660046134ed565b611a1b565b6101276102ca3660046134ed565b611dde565b6101276102dd36600461339b565b611eb2565b3480156102ed575f80fd5b506101fd6102fc3660046133b6565b612236565b61027261030f3660046134ed565b6122ce565b34801561031f575f80fd5b5061017f61032e366004612dee565b6123a5565b34801561033e575f80fd5b5061017f61034d366004613607565b6123b0565b60408051600580825260c082019092525f91816020015b610371612d6e565b8152602001906001900390816103695790505090506103a15f60065f60405180602001604052805f81525061240a565b815f815181106103b3576103b3613645565b60200260200101819052506103d860015f60405180602001604052805f815250612441565b816001815181106103eb576103eb613645565b602002602001018190525061041060025f60405180602001604052805f815250612441565b8160028151811061042357610423613645565b602002602001018190525061044860045f60405180602001604052805f815250612441565b8160038151811061045b5761045b613645565b602002602001018190525061048060035f60405180602001604052805f815250612441565b8160048151811061049357610493613645565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f604051806101200160405280600280546104e890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461051490613659565b801561055f5780601f106105365761010080835404028352916020019161055f565b820191905f5260205f20905b81548152906001019060200180831161054257829003601f168201915b505050505081526020016003805461057690613659565b80601f01602080910402602001604051908101604052809291908181526020018280546105a290613659565b80156105ed5780601f106105c4576101008083540402835291602001916105ed565b820191905f5260205f20905b8154815290600101906020018083116105d057829003601f168201915b50505050508152602001866001600160a01b031681526020016004805461061390613659565b80601f016020809104026020016040519081016040528092919081815260200182805461063f90613659565b801561068a5780601f106106615761010080835404028352916020019161068a565b820191905f5260205f20905b81548152906001019060200180831161066d57829003601f168201915b5050509183525050600160208201819052600554600160401b810460070b6040840152600160a01b900460ff16151560608301526080820186905260a09091018490529091505f9060405190808252806020026020018201604052801561072957816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816106f05790505b506040805160a081018252600181526001600160a01b0380891660208301525f928201839052606082018390528916608082015282519293509183919061077257610772613645565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816107935790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b8152602001876001600160a01b031681526020015f15158152602001886001600160a01b0316815250815f8151811061083457610834613645565b60200260200101819052505f8061084c858585612476565b90925090506016821461085d575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050565b5f6108af8383612596565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146108f9575f80fd5b92915050565b5f61090a8383612674565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161093d91815260200190565b60405180910390a1601681146108f9575f80fd5b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109cf9190613691565b5f604051808303815f865af19150503d805f8114610a08576040519150601f19603f3d011682016040523d82523d5f602084013e610a0d565b606091505b509150915081610a1e576015610a32565b80806020019051810190610a3291906136bd565b60030b979650505050505050565b5f61090a838361269e565b60408051600680825260e082019092525f91816020015b610a6a612d6e565b815260200190600190039081610a62579050509050610a9a5f60065f60405180602001604052805f81525061240a565b815f81518110610aac57610aac613645565b6020026020010181905250610ad160015f60405180602001604052805f815250612441565b81600181518110610ae457610ae4613645565b6020026020010181905250610b0960025f60405180602001604052805f815250612441565b81600281518110610b1c57610b1c613645565b6020026020010181905250610b4160035f60405180602001604052805f815250612441565b81600381518110610b5457610b54613645565b6020026020010181905250610b7960045f60405180602001604052805f815250612441565b81600481518110610b8c57610b8c613645565b6020026020010181905250610bb160055f60405180602001604052805f815250612441565b81600581518110610bc457610bc4613645565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054610c1990613659565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4590613659565b8015610c905780601f10610c6757610100808354040283529160200191610c90565b820191905f5260205f20905b815481529060010190602001808311610c7357829003601f168201915b5050505050815260200160038054610ca790613659565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd390613659565b8015610d1e5780601f10610cf557610100808354040283529160200191610d1e565b820191905f5260205f20905b815481529060010190602001808311610d0157829003601f168201915b50505050508152602001856001600160a01b0316815260200160048054610d4490613659565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7090613659565b8015610dbb5780601f10610d9257610100808354040283529160200191610dbb565b820191905f5260205f20905b815481529060010190602001808311610d9e57829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f918291610e1e91859181900b90600160801b900460030b6126c8565b909250905060168214610e2f575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050565b5f806060610e82868686612731565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610ec9575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610efa9291906136d6565b60405180910390a1610f27863033845f81518110610f1a57610f1a613645565b6020026020010151612828565b5093509350939050565b5f60605f806101676001600160a01b031663618dc65e60e01b8787604051602401610f5d9291906136f1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f9b9190613691565b5f604051808303815f865af19150503d805f8114610fd4576040519150601f19603f3d011682016040523d82523d5f602084013e610fd9565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161100f929190613712565b60405180910390a18161103257601560405180602001604052805f815250611036565b6016815b60039190910b97909650945050505050565b604051638f74a17b60e01b81525f903090638f74a17b90349061107190889088906004016136f1565b60206040518083038185885af115801561108d573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906110b2919061372c565b60405163f4a01e5b60e01b81523360048201526001600160a01b0382166024820152909150309063f4a01e5b906044016020604051808303815f875af11580156110fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111229190613747565b506040516307e9300f60e11b81526001600160a01b03821660048201523360248201523090630fd2601e906044016020604051808303815f875af115801561116c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611190919061375e565b5061119d8130338561286f565b5050505050565b6040805160018082528183019092525f91816020015b6111c2612d6e565b8152602001906001900390816111ba5790505090506111f15f805f60405180602001604052805f81525061240a565b815f8151811061120357611203613645565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f6040518061012001604052806002805461125890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461128490613659565b80156112cf5780601f106112a6576101008083540402835291602001916112cf565b820191905f5260205f20905b8154815290600101906020018083116112b257829003601f168201915b50505050508152602001600380546112e690613659565b80601f016020809104026020016040519081016040528092919081815260200182805461131290613659565b801561135d5780601f106113345761010080835404028352916020019161135d565b820191905f5260205f20905b81548152906001019060200180831161134057829003601f168201915b50505050508152602001866001600160a01b031681526020016004805461138390613659565b80601f01602080910402602001604051908101604052809291908181526020018280546113af90613659565b80156113fa5780601f106113d1576101008083540402835291602001916113fa565b820191905f5260205f20905b8154815290600101906020018083116113dd57829003601f168201915b5050509183525050600160208201819052600554600160401b900460070b6040808401919091525f606084018190526080840188905260a09093018690528051828152808201909152929350909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f1990920191018161144e5750506040805160a081018252606481526001600160a01b0388811660208301525f92820183905260608201839052891660808201528251929350918391906114ce576114ce613645565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816114ef5750506040805160c0810182526004815260056020820152600a91810191909152601e60608201525f608082018190526001600160a01b038a1660a08301528251929350909183919061158057611580613645565b60209081029190910101526005545f9081906115af908690600781900b90600160801b900460030b87876128b6565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa826040516115e491815260200190565b60405180910390a16016821461085d575f80fd5b60408051600680825260e082019092525f91829190816020015b61161a612d6e565b81526020019060019003908161161257905050905061163d5f600660038661240a565b815f8151811061164f5761164f613645565b60200260200101819052506116676001600385612441565b8160018151811061167a5761167a613645565b60200260200101819052506116926002600385612441565b816002815181106116a5576116a5613645565b60200260200101819052506116bd6004600385612441565b816003815181106116d0576116d0613645565b60200260200101819052506116e760038085612441565b816004815181106116fa576116fa613645565b60200260200101819052506117126005600385612441565b8160058151811061172557611725613645565b60200260200101819052505f60405180606001604052805f60070b8152602001866001600160a01b03168152602001627a120060070b81525090505f6040518061012001604052806002805461177a90613659565b80601f01602080910402602001604051908101604052809291908181526020018280546117a690613659565b80156117f15780601f106117c8576101008083540402835291602001916117f1565b820191905f5260205f20905b8154815290600101906020018083116117d457829003601f168201915b505050505081526020016003805461180890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461183490613659565b801561187f5780601f106118565761010080835404028352916020019161187f565b820191905f5260205f20905b81548152906001019060200180831161186257829003601f168201915b50505050508152602001876001600160a01b03168152602001600480546118a590613659565b80601f01602080910402602001604051908101604052809291908181526020018280546118d190613659565b801561191c5780601f106118f35761010080835404028352916020019161191c565b820191905f5260205f20905b8154815290600101906020018083116118ff57829003601f168201915b505050918352505060016020820152600554600160401b8104600790810b604084015260ff600160a01b830416151560608401526080830187905260a09092018590529192505f91829161197f91859181900b90600160801b900460030b6126c8565b909250905060168214611990575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1979650505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610991565b60408051600680825260e082019092525f91816020015b611a3a612d6e565b815260200190600190039081611a32579050509050611a5d5f600660038561240a565b815f81518110611a6f57611a6f613645565b6020026020010181905250611a876001600384612441565b81600181518110611a9a57611a9a613645565b6020026020010181905250611ab26002600384612441565b81600281518110611ac557611ac5613645565b6020026020010181905250611add6004600384612441565b81600381518110611af057611af0613645565b6020026020010181905250611b0760038084612441565b81600481518110611b1a57611b1a613645565b6020026020010181905250611b326005600384612441565b81600581518110611b4557611b45613645565b60200260200101819052505f60405180606001604052805f60070b8152602001856001600160a01b03168152602001627a120060070b81525090505f60405180610120016040528060028054611b9a90613659565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc690613659565b8015611c115780601f10611be857610100808354040283529160200191611c11565b820191905f5260205f20905b815481529060010190602001808311611bf457829003601f168201915b5050505050815260200160038054611c2890613659565b80601f0160208091040260200160405190810160405280929190818152602001828054611c5490613659565b8015611c9f5780601f10611c7657610100808354040283529160200191611c9f565b820191905f5260205f20905b815481529060010190602001808311611c8257829003601f168201915b50505050508152602001866001600160a01b0316815260200160048054611cc590613659565b80601f0160208091040260200160405190810160405280929190818152602001828054611cf190613659565b8015611d3c5780601f10611d1357610100808354040283529160200191611d3c565b820191905f5260205f20905b815481529060010190602001808311611d1f57829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80611d88836129dc565b909250905060168214611d99575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050565b60408051600480825260a082019092525f91816020015b611dfd612d6e565b815260200190600190039081611df5579050509050611e205f600660038561240a565b815f81518110611e3257611e32613645565b6020026020010181905250611e4a6002600384612441565b81600181518110611e5d57611e5d613645565b6020026020010181905250611e756004600384612441565b81600281518110611e8857611e88613645565b6020026020010181905250611e9f60038084612441565b81600381518110611b4557611b45613645565b60408051600580825260c082019092525f91816020015b611ed1612d6e565b815260200190600190039081611ec9579050509050611f015f60065f60405180602001604052805f81525061240a565b815f81518110611f1357611f13613645565b6020026020010181905250611f3860015f60405180602001604052805f815250612441565b81600181518110611f4b57611f4b613645565b6020026020010181905250611f7060025f60405180602001604052805f815250612441565b81600281518110611f8357611f83613645565b6020026020010181905250611fa860045f60405180602001604052805f815250612441565b81600381518110611fbb57611fbb613645565b6020026020010181905250611fe060035f60405180602001604052805f815250612441565b81600481518110611ff357611ff3613645565b60200260200101819052505f60405180606001604052805f60070b8152602001846001600160a01b03168152602001627a120060070b81525090505f6040518061012001604052806002805461204890613659565b80601f016020809104026020016040519081016040528092919081815260200182805461207490613659565b80156120bf5780601f10612096576101008083540402835291602001916120bf565b820191905f5260205f20905b8154815290600101906020018083116120a257829003601f168201915b50505050508152602001600380546120d690613659565b80601f016020809104026020016040519081016040528092919081815260200182805461210290613659565b801561214d5780601f106121245761010080835404028352916020019161214d565b820191905f5260205f20905b81548152906001019060200180831161213057829003601f168201915b50505050508152602001856001600160a01b031681526020016004805461217390613659565b80601f016020809104026020016040519081016040528092919081815260200182805461219f90613659565b80156121ea5780601f106121c1576101008083540402835291602001916121ea565b820191905f5260205f20905b8154815290600101906020018083116121cd57829003601f168201915b505050918352505060016020820152600554600160401b810460070b6040830152600160a01b900460ff16151560608201526080810185905260a00183905290505f80610e1e836129dc565b5f806060612245868686612731565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a16016831461228c575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d82826040516122bd9291906136d6565b60405180910390a193509350939050565b60408051600480825260a082019092525f91829190816020015b6122f0612d6e565b8152602001906001900390816122e85790505090506123135f600660038661240a565b815f8151811061232557612325613645565b602002602001018190525061233d6002600385612441565b8160018151811061235057612350613645565b60200260200101819052506123686004600385612441565b8160028151811061237b5761237b613645565b602002602001018190525061239260038085612441565b8160038151811061172557611725613645565b5f61090a8383612ae4565b5f6123bc848484612b19565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa816040516123ef91815260200190565b60405180910390a160168114612403575f80fd5b9392505050565b612412612d6e565b60405180604001604052806124278787612bed565b81526020016124368585612c27565b905295945050505050565b612449612d6e565b604051806040016040528061245d86612d32565b815260200161246c8585612c27565b9052949350505050565b5f80848061010001515f015160070b5f14801561249d57506101008101516040015160070b155b156124b3576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a6040516024016124df939291906139ab565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161251d9190613691565b5f6040518083038185875af1925050503d805f8114612557576040519150601f19603f3d011682016040523d82523d5f602084013e61255c565b606091505b50915091508161256e5760155f612582565b808060200190518101906125829190613a62565b60039190910b999098509650505050505050565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516126059190613691565b5f604051808303815f865af19150503d805f811461263e576040519150601f19603f3d011682016040523d82523d5f602084013e612643565b606091505b509150915081612654576015612668565b8080602001905181019061266891906136bd565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b86866040516024016125c7929190613a8c565b5f805f6101676001600160a01b0316637d305cfa60e01b86866040516024016125c7929190613ae7565b5f80848061010001515f015160070b5f1480156126ef57506101008101516040015160070b155b15612705576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a6040516024016124df93929190613b08565b5f8060605f806101676001600160a01b031663e0f4059a60e01b89898960405160240161276093929190613b36565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161279e9190613691565b5f604051808303815f865af19150503d805f81146127d7576040519150601f19603f3d011682016040523d82523d5f602084013e6127dc565b606091505b5091509150816127fe57604080515f8082526020820190925260159190612812565b808060200190518101906128129190613bb3565b60039290920b9a90995090975095505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610991565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610991565b5f80868061010001515f015160070b5f1480156128dd57506101008101516040015160070b155b156128f3576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c604051602401612923959493929190613c6d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516129619190613691565b5f6040518083038185875af1925050503d805f811461299b576040519150601f19603f3d011682016040523d82523d5f602084013e6129a0565b606091505b5091509150816129b25760155f6129c6565b808060200190518101906129c69190613a62565b60039190910b9b909a5098505050505050505050565b5f80828061010001515f015160070b5f148015612a0357506101008101516040015160070b155b15612a19576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b88604051602401612a419190613d38565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612a7f9190613691565b5f6040518083038185875af1925050503d805f8114612ab9576040519150601f19603f3d011682016040523d82523d5f602084013e612abe565b606091505b509150915081612ad05760155f611036565b808060200190518101906110369190613a62565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b906064016125c7565b604080516001600160a01b03858116602483015284166044820152606480820184905282518083039091018152608490910182526020810180516001600160e01b031663e1f21c6760e01b17905290515f918291829161016791612b7d9190613691565b5f604051808303815f865af19150503d805f8114612bb6576040519150601f19603f3d011682016040523d82523d5f602084013e612bbb565b606091505b509150915081612bcc576015612be0565b80806020019051810190612be091906136bd565b60030b9695505050505050565b5f612c10836006811115612c0357612c03613d4a565b600160ff9091161b821790565b9050612403826006811115612c0357612c03613d4a565b612c6a6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b5f836004811115612c7d57612c7d613d4a565b03612c8b57600181526108f9565b6001836004811115612c9f57612c9f613d4a565b03612cb9575f546001600160a01b031660208201526108f9565b6002836004811115612ccd57612ccd613d4a565b03612cde57604081018290526108f9565b6003836004811115612cf257612cf2613d4a565b03612d0357606081018290526108f9565b6004836004811115612d1757612d17613d4a565b036108f9575f546001600160a01b0316608082015292915050565b5f60015f836006811115612d4857612d48613d4a565b6006811115612d5957612d59613d4a565b81526020019081526020015f20549050919050565b60405180604001604052805f8152602001612dc26040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b905290565b6001600160a01b0381168114612ddb575f80fd5b50565b8035612de981612dc7565b919050565b5f8060408385031215612dff575f80fd5b8235612e0a81612dc7565b91506020830135612e1a81612dc7565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715612e5c57612e5c612e25565b60405290565b60405160a0810167ffffffffffffffff81118282101715612e5c57612e5c612e25565b604051610120810167ffffffffffffffff81118282101715612e5c57612e5c612e25565b604051601f8201601f1916810167ffffffffffffffff81118282101715612ed257612ed2612e25565b604052919050565b5f67ffffffffffffffff821115612ef357612ef3612e25565b5060051b60200190565b5f8060408385031215612f0e575f80fd5b8235612f1981612dc7565b915060208381013567ffffffffffffffff811115612f35575f80fd5b8401601f81018613612f45575f80fd5b8035612f58612f5382612eda565b612ea9565b81815260059190911b82018301908381019088831115612f76575f80fd5b928401925b82841015612f9d578335612f8e81612dc7565b82529284019290840190612f7b565b80955050505050509250929050565b5f805f8060808587031215612fbf575f80fd5b8435612fca81612dc7565b93506020850135612fda81612dc7565b92506040850135612fea81612dc7565b9396929550929360600135925050565b5f82601f830112613009575f80fd5b813567ffffffffffffffff81111561302357613023612e25565b613036601f8201601f1916602001612ea9565b81815284602083860101111561304a575f80fd5b816020850160208301375f918101602001919091529392505050565b80358015158114612de9575f80fd5b8060070b8114612ddb575f80fd5b8035612de981613075565b5f82601f83011261309d575f80fd5b813560206130ad612f5383612eda565b82815260059290921b840181019181810190868411156130cb575f80fd5b8286015b848110156131dc57803567ffffffffffffffff808211156130ee575f80fd5b908801906040601f19838c038101821315613107575f80fd5b61310f612e39565b8885013581528285013584811115613125575f80fd5b949094019360a0858e038301121561313b575f80fd5b613143612e62565b9150613150898601613066565b82528285013561315f81612dc7565b828a015260608581013585811115613175575f80fd5b6131838f8c838a0101612ffa565b858501525060809350838601358581111561319c575f80fd5b6131aa8f8c838a0101612ffa565b82850152505060a085013594506131c085612dc7565b91810193909352808701929092525083529183019183016130cf565b509695505050505050565b5f606082840312156131f7575f80fd5b6040516060810181811067ffffffffffffffff8211171561321a5761321a612e25565b604052905080823561322b81613075565b8152602083013561323b81612dc7565b6020820152604083013561324e81613075565b6040919091015292915050565b5f806040838503121561326c575f80fd5b823561327781612dc7565b9150602083013567ffffffffffffffff80821115613293575f80fd5b9084019061016082870312156132a7575f80fd5b6132af612e85565b8235828111156132bd575f80fd5b6132c988828601612ffa565b8252506020830135828111156132dd575f80fd5b6132e988828601612ffa565b6020830152506132fb60408401612dde565b6040820152606083013582811115613311575f80fd5b61331d88828601612ffa565b60608301525061332f60808401613066565b608082015261334060a08401613083565b60a082015261335160c08401613066565b60c082015260e083013582811115613367575f80fd5b6133738882860161308e565b60e083015250610100915061338a878385016131e7565b828201528093505050509250929050565b5f602082840312156133ab575f80fd5b813561240381612dc7565b5f805f606084860312156133c8575f80fd5b83356133d381612dc7565b92506020848101356133e481613075565b9250604085013567ffffffffffffffff80821115613400575f80fd5b818701915087601f830112613413575f80fd5b8135613421612f5382612eda565b81815260059190911b8301840190848101908a83111561343f575f80fd5b8585015b8381101561347557803585811115613459575f80fd5b6134678d89838a0101612ffa565b845250918601918601613443565b508096505050505050509250925092565b5f815180845260208085019450602084015f5b838110156134b857815160070b87529582019590820190600101613499565b509495945050505050565b8381528260070b6020820152606060408201525f6134e46060830184613486565b95945050505050565b5f80604083850312156134fe575f80fd5b823561350981612dc7565b9150602083013567ffffffffffffffff811115613524575f80fd5b61353085828601612ffa565b9150509250929050565b5f5b8381101561355457818101518382015260200161353c565b50505f910152565b5f815180845261357381602086016020860161353a565b601f01601f19169290920160200192915050565b828152604060208201525f61359f604083018461355c565b949350505050565b5f805f606084860312156135b9575f80fd5b83356135c481612dc7565b9250602084013567ffffffffffffffff8111156135df575f80fd5b6135eb86828701612ffa565b92505060408401356135fc81613075565b809150509250925092565b5f805f60608486031215613619575f80fd5b833561362481612dc7565b9250602084013561363481612dc7565b929592945050506040919091013590565b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168061366d57607f821691505b60208210810361368b57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f82516136a281846020870161353a565b9190910192915050565b8051600381900b8114612de9575f80fd5b5f602082840312156136cd575f80fd5b612403826136ac565b8260070b8152604060208201525f61359f6040830184613486565b6001600160a01b0383168152604060208201525f61359f604083018461355c565b8215158152604060208201525f61359f604083018461355c565b5f6020828403121561373c575f80fd5b815161240381612dc7565b5f60208284031215613757575f80fd5b5051919050565b5f6020828403121561376e575f80fd5b815161240381613075565b5f82825180855260208086019550808260051b8401018186015f5b8481101561383157601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a01526137f360e08a018661355c565b92860151898403603f1901858b015292945061380f858461355c565b9501511660c09790970196909652505098840198925090830190600101613794565b5090979650505050505050565b5f61016082518185526138538286018261355c565b9150506020830151848203602086015261386d828261355c565b915050604083015161388a60408601826001600160a01b03169052565b50606083015184820360608601526138a2828261355c565b91505060808301516138b8608086018215159052565b5060a08301516138cd60a086018260070b9052565b5060c08301516138e160c086018215159052565b5060e083015184820360e08601526138f98282613779565b9150506101008084015161393582870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b838110156134b8578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101613952565b5f60608083526139be606084018761383e565b6020848203818601526139d1828861393f565b915060408583036040870152828751808552838501915083890194505f5b81811015613a525785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c0909201916001016139ef565b50909a9950505050505050505050565b5f8060408385031215613a73575f80fd5b613a7c836136ac565b91506020830151612e1a81612dc7565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015613ad9578551851683529483019491830191600101613abb565b509098975050505050505050565b6001600160a01b0383168152604060208201525f61359f604083018461383e565b606081525f613b1a606083018661383e565b90508360070b60208301528260030b6040830152949350505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b82811015613ba457607f19888703018452613b9286835161355c565b95509284019290840190600101613b76565b50939998505050505050505050565b5f805f60608486031215613bc5575f80fd5b613bce846136ac565b9250602080850151613bdf81613075565b604086015190935067ffffffffffffffff811115613bfb575f80fd5b8501601f81018713613c0b575f80fd5b8051613c19612f5382612eda565b81815260059190911b82018301908381019089831115613c37575f80fd5b928401925b82841015613c5e578351613c4f81613075565b82529284019290840190613c3c565b80955050505050509250925092565b5f60a0808352613c8060a084018961383e565b602060078960070b8287015260408960030b604088015260608785036060890152613cab858b61393f565b9450608088860360808a0152858a518088528688019150868c0197505f5b81811015613d235788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c090920191600101613cc9565b50909f9e505050505050505050505050505050565b602081525f612403602083018461383e565b634e487b7160e01b5f52602160045260245ffdfea2646970667358221220ff1f32f09b2f502361a23acdef2eeef747b3329dc66049e880f3ad4bdcc9203b64736f6c63430008180033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json index 8d0612827..b0a8bd740 100644 --- a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json +++ b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json @@ -92,6 +92,35 @@ "name": "TransferToken", "type": "event" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approvePublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -239,11 +268,6 @@ "name": "treasury", "type": "address" }, - { - "internalType": "address", - "name": "fixedFeeTokenAddress", - "type": "address" - }, { "internalType": "string", "name": "name", @@ -275,9 +299,73 @@ "type": "int32" }, { - "internalType": "int64", - "name": "feeAmount", - "type": "int64" + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "minimumAmount", + "type": "int64" + }, + { + "internalType": "int64", + "name": "maximumAmount", + "type": "int64" + }, + { + "internalType": "bool", + "name": "netOfTransfers", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FractionalFee[]", + "name": "fractionalFees", + "type": "tuple[]" }, { "components": [ @@ -329,6 +417,54 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "memo", + "type": "string" + }, + { + "internalType": "int64", + "name": "initialTotalSupply", + "type": "int64" + }, + { + "internalType": "int64", + "name": "maxSupply", + "type": "int64" + }, + { + "internalType": "int32", + "name": "decimals", + "type": "int32" + }, + { + "internalType": "bool", + "name": "freezeDefaultStatus", + "type": "bool" + }, + { + "internalType": "address", + "name": "treasury", + "type": "address" + } + ], + "name": "createFungibleTokenWithPresetKeys", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -413,11 +549,6 @@ "name": "treasury", "type": "address" }, - { - "internalType": "address", - "name": "fixedFeeTokenAddress", - "type": "address" - }, { "internalType": "string", "name": "name", @@ -439,9 +570,73 @@ "type": "int64" }, { - "internalType": "int64", - "name": "feeAmount", - "type": "int64" + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.RoyaltyFee[]", + "name": "royaltyFees", + "type": "tuple[]" }, { "components": [ @@ -742,8 +937,8 @@ "type": "function" } ], - "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a55612480806101235f395ff3fe6080604052600436106100ce575f3560e01c8063618dc65e1161007c578063c827bd3211610057578063c827bd32146101ef578063de84a7791461021d578063f4a01e5b1461023c578063fec394da1461025b575f80fd5b8063618dc65e146101905780639b23d3d9146101bd578063bb330b12146101dc575f80fd5b806329fc46e6116100ac57806329fc46e614610155578063424f165e1461016a57806353b4f6781461017d575f80fd5b80630fd2601e146100d2578063118741e71461010957806315dacbea14610136575b5f80fd5b3480156100dd575f80fd5b506100f16100ec3660046113e7565b61027a565b60405160079190910b81526020015b60405180910390f35b348015610114575f80fd5b506101286101233660046114d2565b6102d5565b604051908152602001610100565b348015610141575f80fd5b506100f1610150366004611581565b610327565b6101686101633660046117d5565b610416565b005b6101686101783660046118cc565b6104ee565b61016861018b366004611991565b6105c0565b34801561019b575f80fd5b506101af6101aa366004611a78565b61080c565b604051610100929190611b12565b3480156101c8575f80fd5b506100f16101d7366004611581565b610923565b6101686101ea366004611b32565b610967565b3480156101fa575f80fd5b5061020e610209366004611cb6565b610bea565b60405161010093929190611d64565b348015610228575f80fd5b5061020e610237366004611d8e565b610c82565b348015610247575f80fd5b506101286102563660046113e7565b610d1a565b348015610266575f80fd5b5061020e610275366004611cb6565b610d25565b5f6102858383610d47565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146102cf575f80fd5b92915050565b5f6102e08383610e25565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161031391815260200190565b60405180910390a1601681146102cf575f80fd5b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516103a59190611dec565b5f604051808303815f865af19150503d805f81146103de576040519150601f19603f3d011682016040523d82523d5f602084013e6103e3565b606091505b5091509150816103f4576015610408565b808060200190518101906104089190611e07565b60030b979650505050505050565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528f81529081018e9052948501529083018a905260016080840152600788900b60a084015285151560c084015260e08301849052610100830182905290919080610492838b8a610e4f565b9092509050601682146104a3575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050505050565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528c81529081018b90529485015290830187905260016080840152600786900b60a084015260c0830181905260e0830184905261010083018290529091908061056783610f6f565b909250905060168214610578575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050565b60408051606080820183525f8083526001600160a01b038c166020808501829052627a1200858701528551610120810187528c81529081018b905280860191909152918201889052600160808301819052600788900b60a084015260c0830182905260e083018690526101008301849052845181815280860190955292939192909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816106485790505090506040518060a001604052808660070b81526020018b6001600160a01b031681526020015f151581526020015f151581526020018c6001600160a01b0316815250815f815181106106d5576106d5611e29565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816106f65790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b81526020018c6001600160a01b031681526020015f151581526020018d6001600160a01b0316815250815f8151811061079757610797611e29565b60200260200101819052505f806107af858585611077565b9092509050601682146107c0575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a15050505050505050505050505050565b5f60605f806101676001600160a01b031663618dc65e60e01b8787604051602401610838929190611e3d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108769190611dec565b5f604051808303815f865af19150503d805f81146108af576040519150601f19603f3d011682016040523d82523d5f602084013e6108b4565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc82826040516108ea929190611e5e565b60405180910390a18161090d57601560405180602001604052805f815250610911565b6016815b60039190910b97909650945050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610367565b60408051606080820183525f8083526001600160a01b038e166020808501829052627a1200858701528551610120810187528e81529081018d9052808601919091529182018a9052600160808301819052600789900b60a084015260c0830182905260e083018690526101008301849052845181815280860190955292939192909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816109ef5790505090506040518060a001604052808660070b81526020018d6001600160a01b031681526020015f151581526020015f151581526020018e6001600160a01b0316815250815f81518110610a7c57610a7c611e29565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f19909201910181610a9d5790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b8152602001601e60070b81526020015f151581526020018f6001600160a01b0316815250815f81518110610b3957610b39611e29565b60200260200101819052505f80610b53858c8b87876110e0565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa82604051610b8891815260200190565b60405180910390a160168214610b9c575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050505050505050565b5f806060610bf9878686610c82565b809350819450829550505050610c2a873088845f81518110610c1d57610c1d611e29565b6020026020010151611206565b50604080516001600160a01b03898116825288166020820152600787900b8183015290517f215c8eec9aa8fa57cdc8525400a046bf00ff93b20cc529980e01c1ef114fc2289181900360600190a19450945094915050565b5f806060610c9186868661124d565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610cd8575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610d09929190611e78565b60405180910390a193509350939050565b5f6102e08383611344565b5f806060610d34878686610c82565b91945092509050610c2a87308888611379565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610db69190611dec565b5f604051808303815f865af19150503d805f8114610def576040519150601f19603f3d011682016040523d82523d5f602084013e610df4565b606091505b509150915081610e05576015610e19565b80806020019051810190610e199190611e07565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b8686604051602401610d78929190611e93565b5f80848061010001515f015160070b5f148015610e7657506101008101516040015160070b155b15610e8c576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a604051602401610eb8939291906120b4565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610ef69190611dec565b5f6040518083038185875af1925050503d805f8114610f30576040519150601f19603f3d011682016040523d82523d5f602084013e610f35565b606091505b509150915081610f475760155f610f5b565b80806020019051810190610f5b91906120e2565b60039190910b999098509650505050505050565b5f80828061010001515f015160070b5f148015610f9657506101008101516040015160070b155b15610fac576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b88604051602401610fd4919061210f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516110129190611dec565b5f6040518083038185875af1925050503d805f811461104c576040519150601f19603f3d011682016040523d82523d5f602084013e611051565b606091505b5091509150816110635760155f610911565b8080602001905181019061091191906120e2565b5f80848061010001515f015160070b5f14801561109e57506101008101516040015160070b155b156110b4576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a604051602401610eb89392919061218d565b5f80868061010001515f015160070b5f14801561110757506101008101516040015160070b155b1561111d576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c60405160240161114d959493929190612244565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161118b9190611dec565b5f6040518083038185875af1925050503d805f81146111c5576040519150601f19603f3d011682016040523d82523d5f602084013e6111ca565b606091505b5091509150816111dc5760155f6111f0565b808060200190518101906111f091906120e2565b60039190910b9b909a5098505050505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610367565b5f8060605f806101676001600160a01b031663e0f4059a60e01b89898960405160240161127c9392919061230f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516112ba9190611dec565b5f604051808303815f865af19150503d805f81146112f3576040519150601f19603f3d011682016040523d82523d5f602084013e6112f8565b606091505b50915091508161131a57604080515f808252602082019092526015919061132e565b8080602001905181019061132e919061238c565b60039290920b9a90995090975095505050505050565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b90606401610d78565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610367565b6001600160a01b03811681146113d4575f80fd5b50565b80356113e2816113c0565b919050565b5f80604083850312156113f8575f80fd5b8235611403816113c0565b91506020830135611413816113c0565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156114555761145561141e565b60405290565b60405160a0810167ffffffffffffffff811182821017156114555761145561141e565b604051601f8201601f1916810167ffffffffffffffff811182821017156114a7576114a761141e565b604052919050565b5f67ffffffffffffffff8211156114c8576114c861141e565b5060051b60200190565b5f80604083850312156114e3575f80fd5b82356114ee816113c0565b915060208381013567ffffffffffffffff81111561150a575f80fd5b8401601f8101861361151a575f80fd5b803561152d611528826114af565b61147e565b81815260059190911b8201830190838101908883111561154b575f80fd5b928401925b82841015611572578335611563816113c0565b82529284019290840190611550565b80955050505050509250929050565b5f805f8060808587031215611594575f80fd5b843561159f816113c0565b935060208501356115af816113c0565b925060408501356115bf816113c0565b9396929550929360600135925050565b5f82601f8301126115de575f80fd5b813567ffffffffffffffff8111156115f8576115f861141e565b61160b601f8201601f191660200161147e565b81815284602083860101111561161f575f80fd5b816020850160208301375f918101602001919091529392505050565b8060070b81146113d4575f80fd5b80356113e28161163b565b8060030b81146113d4575f80fd5b80356113e281611654565b803580151581146113e2575f80fd5b5f82601f83011261168b575f80fd5b8135602061169b611528836114af565b82815260059290921b840181019181810190868411156116b9575f80fd5b8286015b848110156117ca57803567ffffffffffffffff808211156116dc575f80fd5b908801906040601f19838c0381018213156116f5575f80fd5b6116fd611432565b8885013581528285013584811115611713575f80fd5b949094019360a0858e0383011215611729575f80fd5b61173161145b565b915061173e89860161166d565b82528285013561174d816113c0565b828a015260608581013585811115611763575f80fd5b6117718f8c838a01016115cf565b858501525060809350838601358581111561178a575f80fd5b6117988f8c838a01016115cf565b82850152505060a085013594506117ae856113c0565b91810193909352808701929092525083529183019183016116bd565b509695505050505050565b5f805f805f805f805f6101208a8c0312156117ee575f80fd5b893567ffffffffffffffff80821115611805575f80fd5b6118118d838e016115cf565b9a5060208c0135915080821115611826575f80fd5b6118328d838e016115cf565b995060408c0135915080821115611847575f80fd5b6118538d838e016115cf565b985061186160608d01611649565b975061186f60808d01611649565b965061187d60a08d01611662565b955061188b60c08d0161166d565b945061189960e08d016113d7565b93506101008c01359150808211156118af575f80fd5b506118bc8c828d0161167c565b9150509295985092959850929598565b5f805f805f8060c087890312156118e1575f80fd5b863567ffffffffffffffff808211156118f8575f80fd5b6119048a838b016115cf565b97506020890135915080821115611919575f80fd5b6119258a838b016115cf565b9650604089013591508082111561193a575f80fd5b6119468a838b016115cf565b955061195460608a01611649565b945061196260808a016113d7565b935060a0890135915080821115611977575f80fd5b5061198489828a0161167c565b9150509295509295509295565b5f805f805f805f80610100898b0312156119a9575f80fd5b6119b2896113d7565b97506119c060208a016113d7565b9650604089013567ffffffffffffffff808211156119dc575f80fd5b6119e88c838d016115cf565b975060608b01359150808211156119fd575f80fd5b611a098c838d016115cf565b965060808b0135915080821115611a1e575f80fd5b611a2a8c838d016115cf565b9550611a3860a08c01611649565b9450611a4660c08c01611649565b935060e08b0135915080821115611a5b575f80fd5b50611a688b828c0161167c565b9150509295985092959890939650565b5f8060408385031215611a89575f80fd5b8235611a94816113c0565b9150602083013567ffffffffffffffff811115611aaf575f80fd5b611abb858286016115cf565b9150509250929050565b5f5b83811015611adf578181015183820152602001611ac7565b50505f910152565b5f8151808452611afe816020860160208601611ac5565b601f01601f19169290920160200192915050565b828152604060208201525f611b2a6040830184611ae7565b949350505050565b5f805f805f805f805f806101408b8d031215611b4c575f80fd5b611b558b6113d7565b9950611b6360208c016113d7565b985060408b013567ffffffffffffffff80821115611b7f575f80fd5b611b8b8e838f016115cf565b995060608d0135915080821115611ba0575f80fd5b611bac8e838f016115cf565b985060808d0135915080821115611bc1575f80fd5b611bcd8e838f016115cf565b9750611bdb60a08e01611649565b9650611be960c08e01611649565b9550611bf760e08e01611662565b9450611c066101008e01611649565b93506101208d0135915080821115611c1c575f80fd5b50611c298d828e0161167c565b9150509295989b9194979a5092959850565b5f82601f830112611c4a575f80fd5b81356020611c5a611528836114af565b82815260059290921b84018101918181019086841115611c78575f80fd5b8286015b848110156117ca57803567ffffffffffffffff811115611c9a575f80fd5b611ca88986838b01016115cf565b845250918301918301611c7c565b5f805f8060808587031215611cc9575f80fd5b8435611cd4816113c0565b93506020850135611ce4816113c0565b92506040850135611cf48161163b565b9150606085013567ffffffffffffffff811115611d0f575f80fd5b611d1b87828801611c3b565b91505092959194509250565b5f815180845260208085019450602084015f5b83811015611d5957815160070b87529582019590820190600101611d3a565b509495945050505050565b8381528260070b6020820152606060408201525f611d856060830184611d27565b95945050505050565b5f805f60608486031215611da0575f80fd5b8335611dab816113c0565b92506020840135611dbb8161163b565b9150604084013567ffffffffffffffff811115611dd6575f80fd5b611de286828701611c3b565b9150509250925092565b5f8251611dfd818460208701611ac5565b9190910192915050565b5f60208284031215611e17575f80fd5b8151611e2281611654565b9392505050565b634e487b7160e01b5f52603260045260245ffd5b6001600160a01b0383168152604060208201525f611b2a6040830184611ae7565b8215158152604060208201525f611b2a6040830184611ae7565b8260070b8152604060208201525f611b2a6040830184611d27565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015611ee0578551851683529483019491830191600101611ec2565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611fa657601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a0152611f6860e08a0186611ae7565b92860151898403603f1901858b0152929450611f848584611ae7565b9501511660c09790970196909652505098840198925090830190600101611f09565b5090979650505050505050565b5f6101608251818552611fc882860182611ae7565b91505060208301518482036020860152611fe28282611ae7565b9150506040830151611fff60408601826001600160a01b03169052565b50606083015184820360608601526120178282611ae7565b915050608083015161202d608086018215159052565b5060a083015161204260a086018260070b9052565b5060c083015161205660c086018215159052565b5060e083015184820360e086015261206e8282611eee565b915050610100808401516120aa82870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b606081525f6120c66060830186611fb3565b90508360070b60208301528260030b6040830152949350505050565b5f80604083850312156120f3575f80fd5b82516120fe81611654565b6020840151909250611413816113c0565b602081525f611e226020830184611fb3565b5f815180845260208085019450602084015f5b83811015611d59578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101612134565b5f60608083526121a06060840187611fb3565b6020848203818601526121b38288612121565b915060408583036040870152828751808552838501915083890194505f5b818110156122345785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c0909201916001016121d1565b50909a9950505050505050505050565b5f60a080835261225760a0840189611fb3565b602060078960070b8287015260408960030b604088015260608785036060890152612282858b612121565b9450608088860360808a0152858a518088528688019150868c0197505f5b818110156122fa5788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c0909201916001016122a0565b50909f9e505050505050505050505050505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b8281101561237d57607f1988870301845261236b868351611ae7565b9550928401929084019060010161234f565b50939998505050505050505050565b5f805f6060848603121561239e575f80fd5b83516123a981611654565b809350506020808501516123bc8161163b565b604086015190935067ffffffffffffffff8111156123d8575f80fd5b8501601f810187136123e8575f80fd5b80516123f6611528826114af565b81815260059190911b82018301908381019089831115612414575f80fd5b928401925b8284101561243b57835161242c8161163b565b82529284019290840190612419565b8095505050505050925092509256fea264697066735822122010a2023c07338c6b3303b2a8178f77640bf0604206f0b54a7b16dc66dd94671964736f6c63430008180033", - "deployedBytecode": "0x6080604052600436106100ce575f3560e01c8063618dc65e1161007c578063c827bd3211610057578063c827bd32146101ef578063de84a7791461021d578063f4a01e5b1461023c578063fec394da1461025b575f80fd5b8063618dc65e146101905780639b23d3d9146101bd578063bb330b12146101dc575f80fd5b806329fc46e6116100ac57806329fc46e614610155578063424f165e1461016a57806353b4f6781461017d575f80fd5b80630fd2601e146100d2578063118741e71461010957806315dacbea14610136575b5f80fd5b3480156100dd575f80fd5b506100f16100ec3660046113e7565b61027a565b60405160079190910b81526020015b60405180910390f35b348015610114575f80fd5b506101286101233660046114d2565b6102d5565b604051908152602001610100565b348015610141575f80fd5b506100f1610150366004611581565b610327565b6101686101633660046117d5565b610416565b005b6101686101783660046118cc565b6104ee565b61016861018b366004611991565b6105c0565b34801561019b575f80fd5b506101af6101aa366004611a78565b61080c565b604051610100929190611b12565b3480156101c8575f80fd5b506100f16101d7366004611581565b610923565b6101686101ea366004611b32565b610967565b3480156101fa575f80fd5b5061020e610209366004611cb6565b610bea565b60405161010093929190611d64565b348015610228575f80fd5b5061020e610237366004611d8e565b610c82565b348015610247575f80fd5b506101286102563660046113e7565b610d1a565b348015610266575f80fd5b5061020e610275366004611cb6565b610d25565b5f6102858383610d47565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146102cf575f80fd5b92915050565b5f6102e08383610e25565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161031391815260200190565b60405180910390a1601681146102cf575f80fd5b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516103a59190611dec565b5f604051808303815f865af19150503d805f81146103de576040519150601f19603f3d011682016040523d82523d5f602084013e6103e3565b606091505b5091509150816103f4576015610408565b808060200190518101906104089190611e07565b60030b979650505050505050565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528f81529081018e9052948501529083018a905260016080840152600788900b60a084015285151560c084015260e08301849052610100830182905290919080610492838b8a610e4f565b9092509050601682146104a3575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050505050565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528c81529081018b90529485015290830187905260016080840152600786900b60a084015260c0830181905260e0830184905261010083018290529091908061056783610f6f565b909250905060168214610578575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050565b60408051606080820183525f8083526001600160a01b038c166020808501829052627a1200858701528551610120810187528c81529081018b905280860191909152918201889052600160808301819052600788900b60a084015260c0830182905260e083018690526101008301849052845181815280860190955292939192909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816106485790505090506040518060a001604052808660070b81526020018b6001600160a01b031681526020015f151581526020015f151581526020018c6001600160a01b0316815250815f815181106106d5576106d5611e29565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f199092019101816106f65790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b81526020018c6001600160a01b031681526020015f151581526020018d6001600160a01b0316815250815f8151811061079757610797611e29565b60200260200101819052505f806107af858585611077565b9092509050601682146107c0575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a15050505050505050505050505050565b5f60605f806101676001600160a01b031663618dc65e60e01b8787604051602401610838929190611e3d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108769190611dec565b5f604051808303815f865af19150503d805f81146108af576040519150601f19603f3d011682016040523d82523d5f602084013e6108b4565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc82826040516108ea929190611e5e565b60405180910390a18161090d57601560405180602001604052805f815250610911565b6016815b60039190910b97909650945050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610367565b60408051606080820183525f8083526001600160a01b038e166020808501829052627a1200858701528551610120810187528e81529081018d9052808601919091529182018a9052600160808301819052600789900b60a084015260c0830182905260e083018690526101008301849052845181815280860190955292939192909190816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816109ef5790505090506040518060a001604052808660070b81526020018d6001600160a01b031681526020015f151581526020015f151581526020018e6001600160a01b0316815250815f81518110610a7c57610a7c611e29565b60209081029190910101526040805160018082528183019092525f91816020015b6040805160c0810182525f8082526020808301829052928201819052606082018190526080820181905260a082015282525f19909201910181610a9d5790505090506040518060c00160405280600460070b8152602001600560070b8152602001600a60070b8152602001601e60070b81526020015f151581526020018f6001600160a01b0316815250815f81518110610b3957610b39611e29565b60200260200101819052505f80610b53858c8b87876110e0565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa82604051610b8891815260200190565b60405180910390a160168214610b9c575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050505050505050565b5f806060610bf9878686610c82565b809350819450829550505050610c2a873088845f81518110610c1d57610c1d611e29565b6020026020010151611206565b50604080516001600160a01b03898116825288166020820152600787900b8183015290517f215c8eec9aa8fa57cdc8525400a046bf00ff93b20cc529980e01c1ef114fc2289181900360600190a19450945094915050565b5f806060610c9186868661124d565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610cd8575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610d09929190611e78565b60405180910390a193509350939050565b5f6102e08383611344565b5f806060610d34878686610c82565b91945092509050610c2a87308888611379565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610db69190611dec565b5f604051808303815f865af19150503d805f8114610def576040519150601f19603f3d011682016040523d82523d5f602084013e610df4565b606091505b509150915081610e05576015610e19565b80806020019051810190610e199190611e07565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b8686604051602401610d78929190611e93565b5f80848061010001515f015160070b5f148015610e7657506101008101516040015160070b155b15610e8c576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a604051602401610eb8939291906120b4565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610ef69190611dec565b5f6040518083038185875af1925050503d805f8114610f30576040519150601f19603f3d011682016040523d82523d5f602084013e610f35565b606091505b509150915081610f475760155f610f5b565b80806020019051810190610f5b91906120e2565b60039190910b999098509650505050505050565b5f80828061010001515f015160070b5f148015610f9657506101008101516040015160070b155b15610fac576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b88604051602401610fd4919061210f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516110129190611dec565b5f6040518083038185875af1925050503d805f811461104c576040519150601f19603f3d011682016040523d82523d5f602084013e611051565b606091505b5091509150816110635760155f610911565b8080602001905181019061091191906120e2565b5f80848061010001515f015160070b5f14801561109e57506101008101516040015160070b155b156110b4576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a604051602401610eb89392919061218d565b5f80868061010001515f015160070b5f14801561110757506101008101516040015160070b155b1561111d576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c60405160240161114d959493929190612244565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161118b9190611dec565b5f6040518083038185875af1925050503d805f81146111c5576040519150601f19603f3d011682016040523d82523d5f602084013e6111ca565b606091505b5091509150816111dc5760155f6111f0565b808060200190518101906111f091906120e2565b60039190910b9b909a5098505050505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610367565b5f8060605f806101676001600160a01b031663e0f4059a60e01b89898960405160240161127c9392919061230f565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516112ba9190611dec565b5f604051808303815f865af19150503d805f81146112f3576040519150601f19603f3d011682016040523d82523d5f602084013e6112f8565b606091505b50915091508161131a57604080515f808252602082019092526015919061132e565b8080602001905181019061132e919061238c565b60039290920b9a90995090975095505050505050565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b90606401610d78565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610367565b6001600160a01b03811681146113d4575f80fd5b50565b80356113e2816113c0565b919050565b5f80604083850312156113f8575f80fd5b8235611403816113c0565b91506020830135611413816113c0565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156114555761145561141e565b60405290565b60405160a0810167ffffffffffffffff811182821017156114555761145561141e565b604051601f8201601f1916810167ffffffffffffffff811182821017156114a7576114a761141e565b604052919050565b5f67ffffffffffffffff8211156114c8576114c861141e565b5060051b60200190565b5f80604083850312156114e3575f80fd5b82356114ee816113c0565b915060208381013567ffffffffffffffff81111561150a575f80fd5b8401601f8101861361151a575f80fd5b803561152d611528826114af565b61147e565b81815260059190911b8201830190838101908883111561154b575f80fd5b928401925b82841015611572578335611563816113c0565b82529284019290840190611550565b80955050505050509250929050565b5f805f8060808587031215611594575f80fd5b843561159f816113c0565b935060208501356115af816113c0565b925060408501356115bf816113c0565b9396929550929360600135925050565b5f82601f8301126115de575f80fd5b813567ffffffffffffffff8111156115f8576115f861141e565b61160b601f8201601f191660200161147e565b81815284602083860101111561161f575f80fd5b816020850160208301375f918101602001919091529392505050565b8060070b81146113d4575f80fd5b80356113e28161163b565b8060030b81146113d4575f80fd5b80356113e281611654565b803580151581146113e2575f80fd5b5f82601f83011261168b575f80fd5b8135602061169b611528836114af565b82815260059290921b840181019181810190868411156116b9575f80fd5b8286015b848110156117ca57803567ffffffffffffffff808211156116dc575f80fd5b908801906040601f19838c0381018213156116f5575f80fd5b6116fd611432565b8885013581528285013584811115611713575f80fd5b949094019360a0858e0383011215611729575f80fd5b61173161145b565b915061173e89860161166d565b82528285013561174d816113c0565b828a015260608581013585811115611763575f80fd5b6117718f8c838a01016115cf565b858501525060809350838601358581111561178a575f80fd5b6117988f8c838a01016115cf565b82850152505060a085013594506117ae856113c0565b91810193909352808701929092525083529183019183016116bd565b509695505050505050565b5f805f805f805f805f6101208a8c0312156117ee575f80fd5b893567ffffffffffffffff80821115611805575f80fd5b6118118d838e016115cf565b9a5060208c0135915080821115611826575f80fd5b6118328d838e016115cf565b995060408c0135915080821115611847575f80fd5b6118538d838e016115cf565b985061186160608d01611649565b975061186f60808d01611649565b965061187d60a08d01611662565b955061188b60c08d0161166d565b945061189960e08d016113d7565b93506101008c01359150808211156118af575f80fd5b506118bc8c828d0161167c565b9150509295985092959850929598565b5f805f805f8060c087890312156118e1575f80fd5b863567ffffffffffffffff808211156118f8575f80fd5b6119048a838b016115cf565b97506020890135915080821115611919575f80fd5b6119258a838b016115cf565b9650604089013591508082111561193a575f80fd5b6119468a838b016115cf565b955061195460608a01611649565b945061196260808a016113d7565b935060a0890135915080821115611977575f80fd5b5061198489828a0161167c565b9150509295509295509295565b5f805f805f805f80610100898b0312156119a9575f80fd5b6119b2896113d7565b97506119c060208a016113d7565b9650604089013567ffffffffffffffff808211156119dc575f80fd5b6119e88c838d016115cf565b975060608b01359150808211156119fd575f80fd5b611a098c838d016115cf565b965060808b0135915080821115611a1e575f80fd5b611a2a8c838d016115cf565b9550611a3860a08c01611649565b9450611a4660c08c01611649565b935060e08b0135915080821115611a5b575f80fd5b50611a688b828c0161167c565b9150509295985092959890939650565b5f8060408385031215611a89575f80fd5b8235611a94816113c0565b9150602083013567ffffffffffffffff811115611aaf575f80fd5b611abb858286016115cf565b9150509250929050565b5f5b83811015611adf578181015183820152602001611ac7565b50505f910152565b5f8151808452611afe816020860160208601611ac5565b601f01601f19169290920160200192915050565b828152604060208201525f611b2a6040830184611ae7565b949350505050565b5f805f805f805f805f806101408b8d031215611b4c575f80fd5b611b558b6113d7565b9950611b6360208c016113d7565b985060408b013567ffffffffffffffff80821115611b7f575f80fd5b611b8b8e838f016115cf565b995060608d0135915080821115611ba0575f80fd5b611bac8e838f016115cf565b985060808d0135915080821115611bc1575f80fd5b611bcd8e838f016115cf565b9750611bdb60a08e01611649565b9650611be960c08e01611649565b9550611bf760e08e01611662565b9450611c066101008e01611649565b93506101208d0135915080821115611c1c575f80fd5b50611c298d828e0161167c565b9150509295989b9194979a5092959850565b5f82601f830112611c4a575f80fd5b81356020611c5a611528836114af565b82815260059290921b84018101918181019086841115611c78575f80fd5b8286015b848110156117ca57803567ffffffffffffffff811115611c9a575f80fd5b611ca88986838b01016115cf565b845250918301918301611c7c565b5f805f8060808587031215611cc9575f80fd5b8435611cd4816113c0565b93506020850135611ce4816113c0565b92506040850135611cf48161163b565b9150606085013567ffffffffffffffff811115611d0f575f80fd5b611d1b87828801611c3b565b91505092959194509250565b5f815180845260208085019450602084015f5b83811015611d5957815160070b87529582019590820190600101611d3a565b509495945050505050565b8381528260070b6020820152606060408201525f611d856060830184611d27565b95945050505050565b5f805f60608486031215611da0575f80fd5b8335611dab816113c0565b92506020840135611dbb8161163b565b9150604084013567ffffffffffffffff811115611dd6575f80fd5b611de286828701611c3b565b9150509250925092565b5f8251611dfd818460208701611ac5565b9190910192915050565b5f60208284031215611e17575f80fd5b8151611e2281611654565b9392505050565b634e487b7160e01b5f52603260045260245ffd5b6001600160a01b0383168152604060208201525f611b2a6040830184611ae7565b8215158152604060208201525f611b2a6040830184611ae7565b8260070b8152604060208201525f611b2a6040830184611d27565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015611ee0578551851683529483019491830191600101611ec2565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611fa657601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a0152611f6860e08a0186611ae7565b92860151898403603f1901858b0152929450611f848584611ae7565b9501511660c09790970196909652505098840198925090830190600101611f09565b5090979650505050505050565b5f6101608251818552611fc882860182611ae7565b91505060208301518482036020860152611fe28282611ae7565b9150506040830151611fff60408601826001600160a01b03169052565b50606083015184820360608601526120178282611ae7565b915050608083015161202d608086018215159052565b5060a083015161204260a086018260070b9052565b5060c083015161205660c086018215159052565b5060e083015184820360e086015261206e8282611eee565b915050610100808401516120aa82870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b606081525f6120c66060830186611fb3565b90508360070b60208301528260030b6040830152949350505050565b5f80604083850312156120f3575f80fd5b82516120fe81611654565b6020840151909250611413816113c0565b602081525f611e226020830184611fb3565b5f815180845260208085019450602084015f5b83811015611d59578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101612134565b5f60608083526121a06060840187611fb3565b6020848203818601526121b38288612121565b915060408583036040870152828751808552838501915083890194505f5b818110156122345785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c0909201916001016121d1565b50909a9950505050505050505050565b5f60a080835261225760a0840189611fb3565b602060078960070b8287015260408960030b604088015260608785036060890152612282858b612121565b9450608088860360808a0152858a518088528688019150868c0197505f5b818110156122fa5788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c0909201916001016122a0565b50909f9e505050505050505050505050505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b8281101561237d57607f1988870301845261236b868351611ae7565b9550928401929084019060010161234f565b50939998505050505050505050565b5f805f6060848603121561239e575f80fd5b83516123a981611654565b809350506020808501516123bc8161163b565b604086015190935067ffffffffffffffff8111156123d8575f80fd5b8501601f810187136123e8575f80fd5b80516123f6611528826114af565b81815260059190911b82018301908381019089831115612414575f80fd5b928401925b8284101561243b57835161242c8161163b565b82529284019290840190612419565b8095505050505050925092509256fea264697066735822122010a2023c07338c6b3303b2a8178f77640bf0604206f0b54a7b16dc66dd94671964736f6c63430008180033", + "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a55612b4d806101235f395ff3fe6080604052600436106100e4575f3560e01c8063618dc65e11610087578063e36f755511610057578063e36f755514610252578063f4a01e5b14610265578063f848fec414610284578063fec394da146102a3575f80fd5b8063618dc65e146101b95780639b23d3d9146101e6578063c827bd3214610205578063de84a77914610233575f80fd5b806315dacbea116100c257806315dacbea1461016157806329fc46e614610180578063424f165e1461019357806355a0d9a3146101a6575f80fd5b80630fd2601e146100e8578063118741e71461011f57806311ba467f1461014c575b5f80fd5b3480156100f3575f80fd5b506101076101023660046116bf565b6102c2565b60405160079190910b81526020015b60405180910390f35b34801561012a575f80fd5b5061013e6101393660046117cd565b61031d565b604051908152602001610116565b61015f61015a366004611929565b61036f565b005b34801561016c575f80fd5b5061010761017b3660046119fd565b6105ce565b61015f61018e366004611ba4565b6106bd565b61015f6101a1366004611c9b565b610739565b61015f6101b4366004611f00565b61080b565b3480156101c4575f80fd5b506101d86101d336600461200d565b6108e1565b6040516101169291906120a7565b3480156101f1575f80fd5b506101076102003660046119fd565b6109f8565b348015610210575f80fd5b5061022461021f366004612142565b610a3c565b604051610116939291906121f0565b34801561023e575f80fd5b5061022461024d36600461221a565b610ad4565b61015f61026036600461234c565b610b6c565b348015610270575f80fd5b5061013e61027f3660046116bf565b610c7e565b34801561028f575f80fd5b5061013e61029e36600461247b565b610c89565b3480156102ae575f80fd5b506102246102bd366004612142565b610ce3565b5f6102cd8383610d05565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b601614610317575f80fd5b92915050565b5f6103288383610de3565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161035b91815260200190565b60405180910390a160168114610317575f80fd5b60408051600680825260e082019092525f91816020015b61038e61163f565b8152602001906001900390816103865790505090506103be5f60065f60405180602001604052805f815250610e0d565b815f815181106103d0576103d06124b9565b60200260200101819052506103f560015f60405180602001604052805f815250610e44565b81600181518110610408576104086124b9565b602002602001018190525061042d60025f60405180602001604052805f815250610e44565b81600281518110610440576104406124b9565b602002602001018190525061046560035f60405180602001604052805f815250610e44565b81600381518110610478576104786124b9565b602002602001018190525061049d60045f60405180602001604052805f815250610e44565b816004815181106104b0576104b06124b9565b60200260200101819052506104d560055f60405180602001604052805f815250610e44565b816005815181106104e8576104e86124b9565b60209081029190910181019190915260408051606080820183525f8083526001600160a01b038716838601819052627a1200848601528451610120810186528f81529586018e90529385019390935283018a905260016080840152600788900b60a084015285151560c084015260e083018490526101008301819052919080610572838b8a610e79565b909250905060168214610583575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161064c91906124cd565b5f604051808303815f865af19150503d805f8114610685576040519150601f19603f3d011682016040523d82523d5f602084013e61068a565b606091505b50915091508161069b5760156106af565b808060200190518101906106af91906124e8565b60030b979650505050505050565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528f81529081018e9052948501529083018a905260016080840152600788900b60a084015285151560c084015260e08301849052610100830182905290919080610572838b8a610e79565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528c81529081018b90529485015290830187905260016080840152600786900b60a084015260c0830181905260e083018490526101008301829052909190806107b283610f99565b9092509050601682146107c3575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050565b60408051606080820183525f8083526001600160a01b038c166020808501829052627a1200858701528551610120810187528d81529081018c90529485015290830188905260016080840152600787900b60a084015260c0830181905260e083018490526101008301829052909190806108868388886110a1565b909250905060168214610897575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050505050565b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161090d929190612503565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161094b91906124cd565b5f604051808303815f865af19150503d805f8114610984576040519150601f19603f3d011682016040523d82523d5f602084013e610989565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc82826040516109bf929190612524565b60405180910390a1816109e257601560405180602001604052805f8152506109e6565b6016815b60039190910b97909650945050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a40161060e565b5f806060610a4b878686610ad4565b809350819450829550505050610a7c873088845f81518110610a6f57610a6f6124b9565b602002602001015161110a565b50604080516001600160a01b03898116825288166020820152600787900b8183015290517f215c8eec9aa8fa57cdc8525400a046bf00ff93b20cc529980e01c1ef114fc2289181900360600190a19450945094915050565b5f806060610ae3868686611151565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610b2a575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610b5b92919061253e565b60405180910390a193509350939050565b60408051606080820183525f8083526001600160a01b038e166020808501829052627a1200858701528551610120810187528f81529081018e9052948501529083018a905260016080840152600788900b60a084015260c0830181905260e08301849052610100830182905290919080610be9838b8a8a8a611248565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa82604051610c1e91815260200190565b60405180910390a160168214610c32575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a15050505050505050505050505050565b5f610328838361136e565b5f610c958484846113a3565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa81604051610cc891815260200190565b60405180910390a160168114610cdc575f80fd5b9392505050565b5f806060610cf2878686610ad4565b91945092509050610a7c87308888611477565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610d7491906124cd565b5f604051808303815f865af19150503d805f8114610dad576040519150601f19603f3d011682016040523d82523d5f602084013e610db2565b606091505b509150915081610dc3576015610dd7565b80806020019051810190610dd791906124e8565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b8686604051602401610d36929190612559565b610e1561163f565b6040518060400160405280610e2a87876114be565b8152602001610e3985856114f8565b905295945050505050565b610e4c61163f565b6040518060400160405280610e6086611603565b8152602001610e6f85856114f8565b9052949350505050565b5f80848061010001515f015160070b5f148015610ea057506101008101516040015160070b155b15610eb6576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a604051602401610ee29392919061276d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f2091906124cd565b5f6040518083038185875af1925050503d805f8114610f5a576040519150601f19603f3d011682016040523d82523d5f602084013e610f5f565b606091505b509150915081610f715760155f610f85565b80806020019051810190610f85919061279b565b60039190910b999098509650505050505050565b5f80828061010001515f015160070b5f148015610fc057506101008101516040015160070b155b15610fd6576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b88604051602401610ffe91906127c8565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161103c91906124cd565b5f6040518083038185875af1925050503d805f8114611076576040519150601f19603f3d011682016040523d82523d5f602084013e61107b565b606091505b50915091508161108d5760155f6109e6565b808060200190518101906109e6919061279b565b5f80848061010001515f015160070b5f1480156110c857506101008101516040015160070b155b156110de576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a604051602401610ee293929190612846565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a40161060e565b5f8060605f806101676001600160a01b031663e0f4059a60e01b898989604051602401611180939291906128fd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111be91906124cd565b5f604051808303815f865af19150503d805f81146111f7576040519150601f19603f3d011682016040523d82523d5f602084013e6111fc565b606091505b50915091508161121e57604080515f8082526020820190925260159190611232565b80806020019051810190611232919061297a565b60039290920b9a90995090975095505050505050565b5f80868061010001515f015160070b5f14801561126f57506101008101516040015160070b155b15611285576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c6040516024016112b5959493929190612a38565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516112f391906124cd565b5f6040518083038185875af1925050503d805f811461132d576040519150601f19603f3d011682016040523d82523d5f602084013e611332565b606091505b5091509150816113445760155f611358565b80806020019051810190611358919061279b565b60039190910b9b909a5098505050505050505050565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b90606401610d36565b604080516001600160a01b03858116602483015284166044820152606480820184905282518083039091018152608490910182526020810180516001600160e01b031663e1f21c6760e01b17905290515f91829182916101679161140791906124cd565b5f604051808303815f865af19150503d805f8114611440576040519150601f19603f3d011682016040523d82523d5f602084013e611445565b606091505b50915091508161145657601561146a565b8080602001905181019061146a91906124e8565b60030b9695505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a40161060e565b5f6114e18360068111156114d4576114d4612b03565b600160ff9091161b821790565b9050610cdc8260068111156114d4576114d4612b03565b61153b6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b5f83600481111561154e5761154e612b03565b0361155c5760018152610317565b600183600481111561157057611570612b03565b0361158a575f546001600160a01b03166020820152610317565b600283600481111561159e5761159e612b03565b036115af5760408101829052610317565b60038360048111156115c3576115c3612b03565b036115d45760608101829052610317565b60048360048111156115e8576115e8612b03565b03610317575f546001600160a01b0316608082015292915050565b5f60015f83600681111561161957611619612b03565b600681111561162a5761162a612b03565b81526020019081526020015f20549050919050565b60405180604001604052805f81526020016116936040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b905290565b6001600160a01b03811681146116ac575f80fd5b50565b80356116ba81611698565b919050565b5f80604083850312156116d0575f80fd5b82356116db81611698565b915060208301356116eb81611698565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff8111828210171561172d5761172d6116f6565b60405290565b60405160a0810167ffffffffffffffff8111828210171561172d5761172d6116f6565b60405160c0810167ffffffffffffffff8111828210171561172d5761172d6116f6565b604051601f8201601f1916810167ffffffffffffffff811182821017156117a2576117a26116f6565b604052919050565b5f67ffffffffffffffff8211156117c3576117c36116f6565b5060051b60200190565b5f80604083850312156117de575f80fd5b82356117e981611698565b915060208381013567ffffffffffffffff811115611805575f80fd5b8401601f81018613611815575f80fd5b8035611828611823826117aa565b611779565b81815260059190911b82018301908381019088831115611846575f80fd5b928401925b8284101561186d57833561185e81611698565b8252928401929084019061184b565b80955050505050509250929050565b5f82601f83011261188b575f80fd5b813567ffffffffffffffff8111156118a5576118a56116f6565b6118b8601f8201601f1916602001611779565b8181528460208386010111156118cc575f80fd5b816020850160208301375f918101602001919091529392505050565b8060070b81146116ac575f80fd5b80356116ba816118e8565b8060030b81146116ac575f80fd5b80356116ba81611901565b803580151581146116ba575f80fd5b5f805f805f805f80610100898b031215611941575f80fd5b883567ffffffffffffffff80821115611958575f80fd5b6119648c838d0161187c565b995060208b0135915080821115611979575f80fd5b6119858c838d0161187c565b985060408b013591508082111561199a575f80fd5b506119a78b828c0161187c565b9650506119b660608a016118f6565b94506119c460808a016118f6565b93506119d260a08a0161190f565b92506119e060c08a0161191a565b91506119ee60e08a016116af565b90509295985092959890939650565b5f805f8060808587031215611a10575f80fd5b8435611a1b81611698565b93506020850135611a2b81611698565b92506040850135611a3b81611698565b9396929550929360600135925050565b5f82601f830112611a5a575f80fd5b81356020611a6a611823836117aa565b82815260059290921b84018101918181019086841115611a88575f80fd5b8286015b84811015611b9957803567ffffffffffffffff80821115611aab575f80fd5b908801906040601f19838c038101821315611ac4575f80fd5b611acc61170a565b8885013581528285013584811115611ae2575f80fd5b949094019360a0858e0383011215611af8575f80fd5b611b00611733565b9150611b0d89860161191a565b825282850135611b1c81611698565b828a015260608581013585811115611b32575f80fd5b611b408f8c838a010161187c565b8585015250608093508386013585811115611b59575f80fd5b611b678f8c838a010161187c565b82850152505060a08501359450611b7d85611698565b9181019390935280870192909252508352918301918301611a8c565b509695505050505050565b5f805f805f805f805f6101208a8c031215611bbd575f80fd5b893567ffffffffffffffff80821115611bd4575f80fd5b611be08d838e0161187c565b9a5060208c0135915080821115611bf5575f80fd5b611c018d838e0161187c565b995060408c0135915080821115611c16575f80fd5b611c228d838e0161187c565b9850611c3060608d016118f6565b9750611c3e60808d016118f6565b9650611c4c60a08d0161190f565b9550611c5a60c08d0161191a565b9450611c6860e08d016116af565b93506101008c0135915080821115611c7e575f80fd5b50611c8b8c828d01611a4b565b9150509295985092959850929598565b5f805f805f8060c08789031215611cb0575f80fd5b863567ffffffffffffffff80821115611cc7575f80fd5b611cd38a838b0161187c565b97506020890135915080821115611ce8575f80fd5b611cf48a838b0161187c565b96506040890135915080821115611d09575f80fd5b611d158a838b0161187c565b9550611d2360608a016118f6565b9450611d3160808a016116af565b935060a0890135915080821115611d46575f80fd5b50611d5389828a01611a4b565b9150509295509295509295565b5f82601f830112611d6f575f80fd5b81356020611d7f611823836117aa565b82815260a09283028501820192828201919087851115611d9d575f80fd5b8387015b85811015611e1f5781818a031215611db7575f80fd5b611dbf611733565b8135611dca816118e8565b815281860135611dd981611698565b818701526040611dea83820161191a565b908201526060611dfb83820161191a565b90820152608082810135611e0e81611698565b908201528452928401928101611da1565b5090979650505050505050565b5f82601f830112611e3b575f80fd5b81356020611e4b611823836117aa565b82815260c09283028501820192828201919087851115611e69575f80fd5b8387015b85811015611e1f5781818a031215611e83575f80fd5b611e8b611756565b8135611e96816118e8565b815281860135611ea5816118e8565b81870152604082810135611eb8816118e8565b90820152606082810135611ecb81611698565b908201526080611edc83820161191a565b9082015260a082810135611eef81611698565b908201528452928401928101611e6d565b5f805f805f805f80610100898b031215611f18575f80fd5b611f21896116af565b9750602089013567ffffffffffffffff80821115611f3d575f80fd5b611f498c838d0161187c565b985060408b0135915080821115611f5e575f80fd5b611f6a8c838d0161187c565b975060608b0135915080821115611f7f575f80fd5b611f8b8c838d0161187c565b9650611f9960808c016118f6565b955060a08b0135915080821115611fae575f80fd5b611fba8c838d01611d60565b945060c08b0135915080821115611fcf575f80fd5b611fdb8c838d01611e2c565b935060e08b0135915080821115611ff0575f80fd5b50611ffd8b828c01611a4b565b9150509295985092959890939650565b5f806040838503121561201e575f80fd5b823561202981611698565b9150602083013567ffffffffffffffff811115612044575f80fd5b6120508582860161187c565b9150509250929050565b5f5b8381101561207457818101518382015260200161205c565b50505f910152565b5f815180845261209381602086016020860161205a565b601f01601f19169290920160200192915050565b828152604060208201525f6120bf604083018461207c565b949350505050565b5f82601f8301126120d6575f80fd5b813560206120e6611823836117aa565b82815260059290921b84018101918181019086841115612104575f80fd5b8286015b84811015611b9957803567ffffffffffffffff811115612126575f80fd5b6121348986838b010161187c565b845250918301918301612108565b5f805f8060808587031215612155575f80fd5b843561216081611698565b9350602085013561217081611698565b92506040850135612180816118e8565b9150606085013567ffffffffffffffff81111561219b575f80fd5b6121a7878288016120c7565b91505092959194509250565b5f815180845260208085019450602084015f5b838110156121e557815160070b875295820195908201906001016121c6565b509495945050505050565b8381528260070b6020820152606060408201525f61221160608301846121b3565b95945050505050565b5f805f6060848603121561222c575f80fd5b833561223781611698565b92506020840135612247816118e8565b9150604084013567ffffffffffffffff811115612262575f80fd5b61226e868287016120c7565b9150509250925092565b5f82601f830112612287575f80fd5b81356020612297611823836117aa565b82815260c092830285018201928282019190878511156122b5575f80fd5b8387015b85811015611e1f5781818a0312156122cf575f80fd5b6122d7611756565b81356122e2816118e8565b8152818601356122f1816118e8565b81870152604082810135612304816118e8565b90820152606082810135612317816118e8565b90820152608061232883820161191a565b9082015260a08281013561233b81611698565b9082015284529284019281016122b9565b5f805f805f805f805f806101408b8d031215612366575f80fd5b61236f8b6116af565b995060208b013567ffffffffffffffff8082111561238b575f80fd5b6123978e838f0161187c565b9a5060408d01359150808211156123ac575f80fd5b6123b88e838f0161187c565b995060608d01359150808211156123cd575f80fd5b6123d98e838f0161187c565b98506123e760808e016118f6565b97506123f560a08e016118f6565b965061240360c08e0161190f565b955060e08d0135915080821115612418575f80fd5b6124248e838f01611d60565b94506101008d013591508082111561243a575f80fd5b6124468e838f01612278565b93506101208d013591508082111561245c575f80fd5b506124698d828e01611a4b565b9150509295989b9194979a5092959850565b5f805f6060848603121561248d575f80fd5b833561249881611698565b925060208401356124a881611698565b929592945050506040919091013590565b634e487b7160e01b5f52603260045260245ffd5b5f82516124de81846020870161205a565b9190910192915050565b5f602082840312156124f8575f80fd5b8151610cdc81611901565b6001600160a01b0383168152604060208201525f6120bf604083018461207c565b8215158152604060208201525f6120bf604083018461207c565b8260070b8152604060208201525f6120bf60408301846121b3565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b818110156125a6578551851683529483019491830191600101612588565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611e1f57601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a015261262e60e08a018661207c565b92860151898403603f1901858b015292945061264a858461207c565b9501511660c097909701969096525050988401989250908301906001016125cf565b5f61016082518185526126818286018261207c565b9150506020830151848203602086015261269b828261207c565b91505060408301516126b860408601826001600160a01b03169052565b50606083015184820360608601526126d0828261207c565b91505060808301516126e6608086018215159052565b5060a08301516126fb60a086018260070b9052565b5060c083015161270f60c086018215159052565b5060e083015184820360e086015261272782826125b4565b9150506101008084015161276382870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b606081525f61277f606083018661266c565b90508360070b60208301528260030b6040830152949350505050565b5f80604083850312156127ac575f80fd5b82516127b781611901565b60208401519092506116eb81611698565b602081525f610cdc602083018461266c565b5f815180845260208085019450602084015f5b838110156121e5578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a090960195908201906001016127ed565b5f6060808352612859606084018761266c565b60208482038186015261286c82886127da565b915060408583036040870152828751808552838501915083890194505f5b818110156128ed5785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c09092019160010161288a565b50909a9950505050505050505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b8281101561296b57607f1988870301845261295986835161207c565b9550928401929084019060010161293d565b50939998505050505050505050565b5f805f6060848603121561298c575f80fd5b835161299781611901565b809350506020808501516129aa816118e8565b604086015190935067ffffffffffffffff8111156129c6575f80fd5b8501601f810187136129d6575f80fd5b80516129e4611823826117aa565b81815260059190911b82018301908381019089831115612a02575f80fd5b928401925b82841015612a29578351612a1a816118e8565b82529284019290840190612a07565b80955050505050509250925092565b5f60a0808352612a4b60a084018961266c565b602060078960070b8287015260408960030b604088015260608785036060890152612a76858b6127da565b9450608088860360808a0152858a518088528688019150868c0197505f5b81811015612aee5788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c090920191600101612a94565b50909f9e505050505050505050505050505050565b634e487b7160e01b5f52602160045260245ffdfea264697066735822122053818b786dbae3799f301d1647f2af5a8ff87390b80e788d0391355139a4b8ee64736f6c63430008180033", + "deployedBytecode": "0x6080604052600436106100e4575f3560e01c8063618dc65e11610087578063e36f755511610057578063e36f755514610252578063f4a01e5b14610265578063f848fec414610284578063fec394da146102a3575f80fd5b8063618dc65e146101b95780639b23d3d9146101e6578063c827bd3214610205578063de84a77914610233575f80fd5b806315dacbea116100c257806315dacbea1461016157806329fc46e614610180578063424f165e1461019357806355a0d9a3146101a6575f80fd5b80630fd2601e146100e8578063118741e71461011f57806311ba467f1461014c575b5f80fd5b3480156100f3575f80fd5b506101076101023660046116bf565b6102c2565b60405160079190910b81526020015b60405180910390f35b34801561012a575f80fd5b5061013e6101393660046117cd565b61031d565b604051908152602001610116565b61015f61015a366004611929565b61036f565b005b34801561016c575f80fd5b5061010761017b3660046119fd565b6105ce565b61015f61018e366004611ba4565b6106bd565b61015f6101a1366004611c9b565b610739565b61015f6101b4366004611f00565b61080b565b3480156101c4575f80fd5b506101d86101d336600461200d565b6108e1565b6040516101169291906120a7565b3480156101f1575f80fd5b506101076102003660046119fd565b6109f8565b348015610210575f80fd5b5061022461021f366004612142565b610a3c565b604051610116939291906121f0565b34801561023e575f80fd5b5061022461024d36600461221a565b610ad4565b61015f61026036600461234c565b610b6c565b348015610270575f80fd5b5061013e61027f3660046116bf565b610c7e565b34801561028f575f80fd5b5061013e61029e36600461247b565b610c89565b3480156102ae575f80fd5b506102246102bd366004612142565b610ce3565b5f6102cd8383610d05565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b601614610317575f80fd5b92915050565b5f6103288383610de3565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161035b91815260200190565b60405180910390a160168114610317575f80fd5b60408051600680825260e082019092525f91816020015b61038e61163f565b8152602001906001900390816103865790505090506103be5f60065f60405180602001604052805f815250610e0d565b815f815181106103d0576103d06124b9565b60200260200101819052506103f560015f60405180602001604052805f815250610e44565b81600181518110610408576104086124b9565b602002602001018190525061042d60025f60405180602001604052805f815250610e44565b81600281518110610440576104406124b9565b602002602001018190525061046560035f60405180602001604052805f815250610e44565b81600381518110610478576104786124b9565b602002602001018190525061049d60045f60405180602001604052805f815250610e44565b816004815181106104b0576104b06124b9565b60200260200101819052506104d560055f60405180602001604052805f815250610e44565b816005815181106104e8576104e86124b9565b60209081029190910181019190915260408051606080820183525f8083526001600160a01b038716838601819052627a1200848601528451610120810186528f81529586018e90529385019390935283018a905260016080840152600788900b60a084015285151560c084015260e083018490526101008301819052919080610572838b8a610e79565b909250905060168214610583575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161064c91906124cd565b5f604051808303815f865af19150503d805f8114610685576040519150601f19603f3d011682016040523d82523d5f602084013e61068a565b606091505b50915091508161069b5760156106af565b808060200190518101906106af91906124e8565b60030b979650505050505050565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528f81529081018e9052948501529083018a905260016080840152600788900b60a084015285151560c084015260e08301849052610100830182905290919080610572838b8a610e79565b60408051606080820183525f8083526001600160a01b0386166020808501829052627a1200858701528551610120810187528c81529081018b90529485015290830187905260016080840152600786900b60a084015260c0830181905260e083018490526101008301829052909190806107b283610f99565b9092509050601682146107c3575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a150505050505050505050565b60408051606080820183525f8083526001600160a01b038c166020808501829052627a1200858701528551610120810187528d81529081018c90529485015290830188905260016080840152600787900b60a084015260c0830181905260e083018490526101008301829052909190806108868388886110a1565b909250905060168214610897575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a1505050505050505050505050565b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161090d929190612503565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161094b91906124cd565b5f604051808303815f865af19150503d805f8114610984576040519150601f19603f3d011682016040523d82523d5f602084013e610989565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc82826040516109bf929190612524565b60405180910390a1816109e257601560405180602001604052805f8152506109e6565b6016815b60039190910b97909650945050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a40161060e565b5f806060610a4b878686610ad4565b809350819450829550505050610a7c873088845f81518110610a6f57610a6f6124b9565b602002602001015161110a565b50604080516001600160a01b03898116825288166020820152600787900b8183015290517f215c8eec9aa8fa57cdc8525400a046bf00ff93b20cc529980e01c1ef114fc2289181900360600190a19450945094915050565b5f806060610ae3868686611151565b60405183815292955090935091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a160168314610b2a575f80fd5b7ffc6b20023c4bac8ff1c48c1693e0cea5cd3c2163e9c2da41c58f17dd6d9f163d8282604051610b5b92919061253e565b60405180910390a193509350939050565b60408051606080820183525f8083526001600160a01b038e166020808501829052627a1200858701528551610120810187528f81529081018e9052948501529083018a905260016080840152600788900b60a084015260c0830181905260e08301849052610100830182905290919080610be9838b8a8a8a611248565b915091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa82604051610c1e91815260200190565b60405180910390a160168214610c32575f80fd5b6040516001600160a01b03821681527f7bb17726df1f3adee8aa00ba8e8bc5d6f182af3bbf77604639cb7f008dd3b4ed9060200160405180910390a15050505050505050505050505050565b5f610328838361136e565b5f610c958484846113a3565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa81604051610cc891815260200190565b60405180910390a160168114610cdc575f80fd5b9392505050565b5f806060610cf2878686610ad4565b91945092509050610a7c87308888611477565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610d7491906124cd565b5f604051808303815f865af19150503d805f8114610dad576040519150601f19603f3d011682016040523d82523d5f602084013e610db2565b606091505b509150915081610dc3576015610dd7565b80806020019051810190610dd791906124e8565b60030b95945050505050565b5f805f6101676001600160a01b0316632e63879b60e01b8686604051602401610d36929190612559565b610e1561163f565b6040518060400160405280610e2a87876114be565b8152602001610e3985856114f8565b905295945050505050565b610e4c61163f565b6040518060400160405280610e6086611603565b8152602001610e6f85856114f8565b9052949350505050565b5f80848061010001515f015160070b5f148015610ea057506101008101516040015160070b155b15610eb6576101008101516276a7006040909101525b5f806101676001600160a01b031634630fb65bf360e01b8a8a8a604051602401610ee29392919061276d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610f2091906124cd565b5f6040518083038185875af1925050503d805f8114610f5a576040519150601f19603f3d011682016040523d82523d5f602084013e610f5f565b606091505b509150915081610f715760155f610f85565b80806020019051810190610f85919061279b565b60039190910b999098509650505050505050565b5f80828061010001515f015160070b5f148015610fc057506101008101516040015160070b155b15610fd6576101008101516276a7006040909101525b5f806101676001600160a01b03163463ea83f29360e01b88604051602401610ffe91906127c8565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161103c91906124cd565b5f6040518083038185875af1925050503d805f8114611076576040519150601f19603f3d011682016040523d82523d5f602084013e61107b565b606091505b50915091508161108d5760155f6109e6565b808060200190518101906109e6919061279b565b5f80848061010001515f015160070b5f1480156110c857506101008101516040015160070b155b156110de576101008101516276a7006040909101525b5f806101676001600160a01b03163463abb54eb560e01b8a8a8a604051602401610ee293929190612846565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a40161060e565b5f8060605f806101676001600160a01b031663e0f4059a60e01b898989604051602401611180939291906128fd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111be91906124cd565b5f604051808303815f865af19150503d805f81146111f7576040519150601f19603f3d011682016040523d82523d5f602084013e6111fc565b606091505b50915091508161121e57604080515f8082526020820190925260159190611232565b80806020019051810190611232919061297a565b60039290920b9a90995090975095505050505050565b5f80868061010001515f015160070b5f14801561126f57506101008101516040015160070b155b15611285576101008101516276a7006040909101525b5f806101676001600160a01b031634632af0c59a60e01b8c8c8c8c8c6040516024016112b5959493929190612a38565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516112f391906124cd565b5f6040518083038185875af1925050503d805f811461132d576040519150601f19603f3d011682016040523d82523d5f602084013e611332565b606091505b5091509150816113445760155f611358565b80806020019051810190611358919061279b565b60039190910b9b909a5098505050505050505050565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b90606401610d36565b604080516001600160a01b03858116602483015284166044820152606480820184905282518083039091018152608490910182526020810180516001600160e01b031663e1f21c6760e01b17905290515f91829182916101679161140791906124cd565b5f604051808303815f865af19150503d805f8114611440576040519150601f19603f3d011682016040523d82523d5f602084013e611445565b606091505b50915091508161145657601561146a565b8080602001905181019061146a91906124e8565b60030b9695505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a40161060e565b5f6114e18360068111156114d4576114d4612b03565b600160ff9091161b821790565b9050610cdc8260068111156114d4576114d4612b03565b61153b6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b5f83600481111561154e5761154e612b03565b0361155c5760018152610317565b600183600481111561157057611570612b03565b0361158a575f546001600160a01b03166020820152610317565b600283600481111561159e5761159e612b03565b036115af5760408101829052610317565b60038360048111156115c3576115c3612b03565b036115d45760608101829052610317565b60048360048111156115e8576115e8612b03565b03610317575f546001600160a01b0316608082015292915050565b5f60015f83600681111561161957611619612b03565b600681111561162a5761162a612b03565b81526020019081526020015f20549050919050565b60405180604001604052805f81526020016116936040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b905290565b6001600160a01b03811681146116ac575f80fd5b50565b80356116ba81611698565b919050565b5f80604083850312156116d0575f80fd5b82356116db81611698565b915060208301356116eb81611698565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff8111828210171561172d5761172d6116f6565b60405290565b60405160a0810167ffffffffffffffff8111828210171561172d5761172d6116f6565b60405160c0810167ffffffffffffffff8111828210171561172d5761172d6116f6565b604051601f8201601f1916810167ffffffffffffffff811182821017156117a2576117a26116f6565b604052919050565b5f67ffffffffffffffff8211156117c3576117c36116f6565b5060051b60200190565b5f80604083850312156117de575f80fd5b82356117e981611698565b915060208381013567ffffffffffffffff811115611805575f80fd5b8401601f81018613611815575f80fd5b8035611828611823826117aa565b611779565b81815260059190911b82018301908381019088831115611846575f80fd5b928401925b8284101561186d57833561185e81611698565b8252928401929084019061184b565b80955050505050509250929050565b5f82601f83011261188b575f80fd5b813567ffffffffffffffff8111156118a5576118a56116f6565b6118b8601f8201601f1916602001611779565b8181528460208386010111156118cc575f80fd5b816020850160208301375f918101602001919091529392505050565b8060070b81146116ac575f80fd5b80356116ba816118e8565b8060030b81146116ac575f80fd5b80356116ba81611901565b803580151581146116ba575f80fd5b5f805f805f805f80610100898b031215611941575f80fd5b883567ffffffffffffffff80821115611958575f80fd5b6119648c838d0161187c565b995060208b0135915080821115611979575f80fd5b6119858c838d0161187c565b985060408b013591508082111561199a575f80fd5b506119a78b828c0161187c565b9650506119b660608a016118f6565b94506119c460808a016118f6565b93506119d260a08a0161190f565b92506119e060c08a0161191a565b91506119ee60e08a016116af565b90509295985092959890939650565b5f805f8060808587031215611a10575f80fd5b8435611a1b81611698565b93506020850135611a2b81611698565b92506040850135611a3b81611698565b9396929550929360600135925050565b5f82601f830112611a5a575f80fd5b81356020611a6a611823836117aa565b82815260059290921b84018101918181019086841115611a88575f80fd5b8286015b84811015611b9957803567ffffffffffffffff80821115611aab575f80fd5b908801906040601f19838c038101821315611ac4575f80fd5b611acc61170a565b8885013581528285013584811115611ae2575f80fd5b949094019360a0858e0383011215611af8575f80fd5b611b00611733565b9150611b0d89860161191a565b825282850135611b1c81611698565b828a015260608581013585811115611b32575f80fd5b611b408f8c838a010161187c565b8585015250608093508386013585811115611b59575f80fd5b611b678f8c838a010161187c565b82850152505060a08501359450611b7d85611698565b9181019390935280870192909252508352918301918301611a8c565b509695505050505050565b5f805f805f805f805f6101208a8c031215611bbd575f80fd5b893567ffffffffffffffff80821115611bd4575f80fd5b611be08d838e0161187c565b9a5060208c0135915080821115611bf5575f80fd5b611c018d838e0161187c565b995060408c0135915080821115611c16575f80fd5b611c228d838e0161187c565b9850611c3060608d016118f6565b9750611c3e60808d016118f6565b9650611c4c60a08d0161190f565b9550611c5a60c08d0161191a565b9450611c6860e08d016116af565b93506101008c0135915080821115611c7e575f80fd5b50611c8b8c828d01611a4b565b9150509295985092959850929598565b5f805f805f8060c08789031215611cb0575f80fd5b863567ffffffffffffffff80821115611cc7575f80fd5b611cd38a838b0161187c565b97506020890135915080821115611ce8575f80fd5b611cf48a838b0161187c565b96506040890135915080821115611d09575f80fd5b611d158a838b0161187c565b9550611d2360608a016118f6565b9450611d3160808a016116af565b935060a0890135915080821115611d46575f80fd5b50611d5389828a01611a4b565b9150509295509295509295565b5f82601f830112611d6f575f80fd5b81356020611d7f611823836117aa565b82815260a09283028501820192828201919087851115611d9d575f80fd5b8387015b85811015611e1f5781818a031215611db7575f80fd5b611dbf611733565b8135611dca816118e8565b815281860135611dd981611698565b818701526040611dea83820161191a565b908201526060611dfb83820161191a565b90820152608082810135611e0e81611698565b908201528452928401928101611da1565b5090979650505050505050565b5f82601f830112611e3b575f80fd5b81356020611e4b611823836117aa565b82815260c09283028501820192828201919087851115611e69575f80fd5b8387015b85811015611e1f5781818a031215611e83575f80fd5b611e8b611756565b8135611e96816118e8565b815281860135611ea5816118e8565b81870152604082810135611eb8816118e8565b90820152606082810135611ecb81611698565b908201526080611edc83820161191a565b9082015260a082810135611eef81611698565b908201528452928401928101611e6d565b5f805f805f805f80610100898b031215611f18575f80fd5b611f21896116af565b9750602089013567ffffffffffffffff80821115611f3d575f80fd5b611f498c838d0161187c565b985060408b0135915080821115611f5e575f80fd5b611f6a8c838d0161187c565b975060608b0135915080821115611f7f575f80fd5b611f8b8c838d0161187c565b9650611f9960808c016118f6565b955060a08b0135915080821115611fae575f80fd5b611fba8c838d01611d60565b945060c08b0135915080821115611fcf575f80fd5b611fdb8c838d01611e2c565b935060e08b0135915080821115611ff0575f80fd5b50611ffd8b828c01611a4b565b9150509295985092959890939650565b5f806040838503121561201e575f80fd5b823561202981611698565b9150602083013567ffffffffffffffff811115612044575f80fd5b6120508582860161187c565b9150509250929050565b5f5b8381101561207457818101518382015260200161205c565b50505f910152565b5f815180845261209381602086016020860161205a565b601f01601f19169290920160200192915050565b828152604060208201525f6120bf604083018461207c565b949350505050565b5f82601f8301126120d6575f80fd5b813560206120e6611823836117aa565b82815260059290921b84018101918181019086841115612104575f80fd5b8286015b84811015611b9957803567ffffffffffffffff811115612126575f80fd5b6121348986838b010161187c565b845250918301918301612108565b5f805f8060808587031215612155575f80fd5b843561216081611698565b9350602085013561217081611698565b92506040850135612180816118e8565b9150606085013567ffffffffffffffff81111561219b575f80fd5b6121a7878288016120c7565b91505092959194509250565b5f815180845260208085019450602084015f5b838110156121e557815160070b875295820195908201906001016121c6565b509495945050505050565b8381528260070b6020820152606060408201525f61221160608301846121b3565b95945050505050565b5f805f6060848603121561222c575f80fd5b833561223781611698565b92506020840135612247816118e8565b9150604084013567ffffffffffffffff811115612262575f80fd5b61226e868287016120c7565b9150509250925092565b5f82601f830112612287575f80fd5b81356020612297611823836117aa565b82815260c092830285018201928282019190878511156122b5575f80fd5b8387015b85811015611e1f5781818a0312156122cf575f80fd5b6122d7611756565b81356122e2816118e8565b8152818601356122f1816118e8565b81870152604082810135612304816118e8565b90820152606082810135612317816118e8565b90820152608061232883820161191a565b9082015260a08281013561233b81611698565b9082015284529284019281016122b9565b5f805f805f805f805f806101408b8d031215612366575f80fd5b61236f8b6116af565b995060208b013567ffffffffffffffff8082111561238b575f80fd5b6123978e838f0161187c565b9a5060408d01359150808211156123ac575f80fd5b6123b88e838f0161187c565b995060608d01359150808211156123cd575f80fd5b6123d98e838f0161187c565b98506123e760808e016118f6565b97506123f560a08e016118f6565b965061240360c08e0161190f565b955060e08d0135915080821115612418575f80fd5b6124248e838f01611d60565b94506101008d013591508082111561243a575f80fd5b6124468e838f01612278565b93506101208d013591508082111561245c575f80fd5b506124698d828e01611a4b565b9150509295989b9194979a5092959850565b5f805f6060848603121561248d575f80fd5b833561249881611698565b925060208401356124a881611698565b929592945050506040919091013590565b634e487b7160e01b5f52603260045260245ffd5b5f82516124de81846020870161205a565b9190910192915050565b5f602082840312156124f8575f80fd5b8151610cdc81611901565b6001600160a01b0383168152604060208201525f6120bf604083018461207c565b8215158152604060208201525f6120bf604083018461207c565b8260070b8152604060208201525f6120bf60408301846121b3565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b818110156125a6578551851683529483019491830191600101612588565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611e1f57601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a015261262e60e08a018661207c565b92860151898403603f1901858b015292945061264a858461207c565b9501511660c097909701969096525050988401989250908301906001016125cf565b5f61016082518185526126818286018261207c565b9150506020830151848203602086015261269b828261207c565b91505060408301516126b860408601826001600160a01b03169052565b50606083015184820360608601526126d0828261207c565b91505060808301516126e6608086018215159052565b5060a08301516126fb60a086018260070b9052565b5060c083015161270f60c086018215159052565b5060e083015184820360e086015261272782826125b4565b9150506101008084015161276382870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b606081525f61277f606083018661266c565b90508360070b60208301528260030b6040830152949350505050565b5f80604083850312156127ac575f80fd5b82516127b781611901565b60208401519092506116eb81611698565b602081525f610cdc602083018461266c565b5f815180845260208085019450602084015f5b838110156121e5578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a090960195908201906001016127ed565b5f6060808352612859606084018761266c565b60208482038186015261286c82886127da565b915060408583036040870152828751808552838501915083890194505f5b818110156128ed5785518051600790810b855286820151810b8786015285820151900b85850152878101516001600160a01b039081168986015260808083015115159086015260a09182015116908401529484019460c09092019160010161288a565b50909a9950505050505050505050565b5f606082016001600160a01b038616835260208560070b60208501526060604085015281855180845260808601915060808160051b8701019350602087015f5b8281101561296b57607f1988870301845261295986835161207c565b9550928401929084019060010161293d565b50939998505050505050505050565b5f805f6060848603121561298c575f80fd5b835161299781611901565b809350506020808501516129aa816118e8565b604086015190935067ffffffffffffffff8111156129c6575f80fd5b8501601f810187136129d6575f80fd5b80516129e4611823826117aa565b81815260059190911b82018301908381019089831115612a02575f80fd5b928401925b82841015612a29578351612a1a816118e8565b82529284019290840190612a07565b80955050505050509250925092565b5f60a0808352612a4b60a084018961266c565b602060078960070b8287015260408960030b604088015260608785036060890152612a76858b6127da565b9450608088860360808a0152858a518088528688019150868c0197505f5b81811015612aee5788518051880b845288810151880b8985015286810151880b8785015285810151880b86850152848101511515858501528a01516001600160a01b03168a8401529787019760c090920191600101612a94565b50909f9e505050505050505050505050505050565b634e487b7160e01b5f52602160045260245ffdfea264697066735822122053818b786dbae3799f301d1647f2af5a8ff87390b80e788d0391355139a4b8ee64736f6c63430008180033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json index 23a5d0a04..d54d094fb 100644 --- a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json +++ b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json @@ -456,6 +456,182 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "minimumAmount", + "type": "int64" + }, + { + "internalType": "int64", + "name": "maximumAmount", + "type": "int64" + }, + { + "internalType": "bool", + "name": "netOfTransfers", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FractionalFee[]", + "name": "fractionalFees", + "type": "tuple[]" + } + ], + "name": "updateFungibleTokenCustomFeesPublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.RoyaltyFee[]", + "name": "royaltyFees", + "type": "tuple[]" + } + ], + "name": "updateNonFungibleTokenCustomFeesPublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -746,8 +922,8 @@ "type": "function" } ], - "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a55611af8806101235f395ff3fe608060405234801561000f575f80fd5b5060043610610127575f3560e01c8063815228c0116100a9578063f25b12001161006e578063f25b12001461027c578063f52177ee1461028f578063f7be3425146102ba578063f848fec4146102cd578063fad0038a146102e0575f80fd5b8063815228c01461021d5780639b23d3d914610230578063a345f7bd14610243578063b26d33cb14610256578063df6c06f514610269575f80fd5b806336348de3116100ef57806336348de3146101b05780634d8f27c9146101c357806356af8403146101d6578063618dc65e146101e95780637d3e5da81461020a575f80fd5b806315dacbea1461012b5780632abf6c55146101565780632b256ec8146101775780632d73bb2e1461018a5780632eecbca31461019d575b5f80fd5b61013e610139366004610e2e565b6102f3565b60405160079190910b81526020015b60405180910390f35b610169610164366004610f4e565b6103e2565b60405190815260200161014d565b610169610185366004610ff9565b610427565b610169610198366004611012565b61049f565b61013e6101ab366004611012565b6104cd565b6101696101be36600461129d565b61050f565b61013e6101d13660046113db565b61051a565b6101696101e436600461148b565b610525565b6101fc6101f73660046114e5565b61056c565b60405161014d929190611573565b610169610218366004611012565b610683565b61016961022b366004611593565b61068e565b61013e61023e366004610e2e565b610699565b610169610251366004610ff9565b6106dd565b610169610264366004611012565b610720565b6101696102773660046115bc565b61072b565b61016961028a3660046115f5565b610737565b6102a261029d366004611635565b610743565b6040805192835260079190910b60208301520161014d565b6101696102c8366004610ff9565b610789565b6101696102db3660046115bc565b6107f8565b6101696102ee366004611660565b610804565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161037191906116a4565b5f604051808303815f865af19150503d805f81146103aa576040519150601f19603f3d011682016040523d82523d5f602084013e6103af565b606091505b5091509150816103c05760156103d4565b808060200190518101906103d491906116d0565b60030b979650505050505050565b5f6103ed8383610810565b90505f80516020611aa38339815191528160405161040d91815260200190565b60405180910390a160168114610421575f80fd5b92915050565b5f610431826108e7565b90505f80516020611aa38339815191528160405161045191815260200190565b60405180910390a160168114610465575f80fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b5f6104aa83836109bc565b60070b90505f80516020611aa38339815191528160405161040d91815260200190565b5f6104d883836109f1565b604051600782900b81529091505f80516020611aa38339815191529060200160405180910390a1600781900b601614610421575f80fd5b5f6103ed8383610a26565b5f6104d88383610a50565b5f610531848484610a7a565b90505f80516020611aa38339815191528160405161055191815260200190565b60405180910390a160168114610565575f80fd5b9392505050565b5f60605f806101676001600160a01b031663618dc65e60e01b87876040516024016105989291906116e9565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516105d691906116a4565b5f604051808303815f865af19150503d805f811461060f576040519150601f19603f3d011682016040523d82523d5f602084013e610614565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161064a92919061170a565b60405180910390a18161066d57601560405180602001604052805f815250610671565b6016815b60039190910b97909650945050505050565b5f6104aa8383610b54565b5f6103ed8383610b89565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610333565b5f6106e782610bb3565b90505f80516020611aa38339815191528160405161070791815260200190565b60405180910390a16016811461071b575f80fd5b919050565b5f6103ed8383610be0565b5f610531848484610c15565b5f610531848484610c51565b5f80610750858585610c8e565b60405182815291935091505f80516020611aa38339815191529060200160405180910390a160168214610781575f80fd5b935093915050565b5f61079382610d70565b90505f80516020611aa3833981519152816040516107b391815260200190565b60405180910390a1601681146107c7575f80fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d290602001610492565b5f610531848484610d9d565b5f610531848484610dd9565b5f805f6101676001600160a01b03166378b6391860e01b868660405160240161083a929190611724565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161087891906116a4565b5f604051808303815f865af19150503d805f81146108b1576040519150601f19603f3d011682016040523d82523d5f602084013e6108b6565b606091505b5091509150816108c75760156108db565b808060200190518101906108db91906116d0565b60030b95945050505050565b6040516001600160a01b03821660248201525f908190819061016790631f106b4b60e21b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161094e91906116a4565b5f604051808303815f865af19150503d805f8114610987576040519150601f19603f3d011682016040523d82523d5f602084013e61098c565b606091505b50915091508161099d5760156109b1565b808060200190518101906109b191906116d0565b60030b949350505050565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906352f9138760e01b9060640161083a565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063af99c63360e01b9060640161083a565b5f805f6101676001600160a01b0316637d305cfa60e01b868660405160240161083a929190611844565b5f805f6101676001600160a01b0316636fc3cbaf60e01b868660405160240161083a92919061196e565b5f805f6101676001600160a01b031663f7f38e2660e01b878787604051602401610aa6939291906119cc565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610ae491906116a4565b5f604051808303815f865af19150503d805f8114610b1d576040519150601f19603f3d011682016040523d82523d5f602084013e610b22565b606091505b509150915081610b33576015610b47565b80806020019051810190610b4791906116d0565b60030b9695505050505050565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906316e3e16160e21b9060640161083a565b5f805f6101676001600160a01b031663d27be6cd60e01b868660405160240161083a929190611a00565b6040516001600160a01b03821660248201525f908190819061016790637834fb8960e11b90604401610910565b6040516001600160a01b038381166024830152821660448201525f908190819061016790630132f29d60e31b9060640161083a565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b90608401610aa6565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b90608401610aa6565b5f805f806101676001600160a01b031663d6910d0660e01b888888604051602401610cbb93929190611a43565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610cf991906116a4565b5f604051808303815f865af19150503d805f8114610d32576040519150601f19603f3d011682016040523d82523d5f602084013e610d37565b606091505b509150915081610d495760155f610d5d565b80806020019051810190610d5d9190611a6d565b60039190910b9890975095505050505050565b6040516001600160a01b03821660248201525f908190819061016790633b3bff0f60e01b90604401610910565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b90608401610aa6565b6040516001600160a01b03848116602483015283166044820152600782900b60648201525f90819081906101679063efef57f960e01b90608401610aa6565b80356001600160a01b038116811461071b575f80fd5b5f805f8060808587031215610e41575f80fd5b610e4a85610e18565b9350610e5860208601610e18565b9250610e6660408601610e18565b9396929550929360600135925050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715610ead57610ead610e76565b60405290565b60405160a0810167ffffffffffffffff81118282101715610ead57610ead610e76565b604051610120810167ffffffffffffffff81118282101715610ead57610ead610e76565b604051601f8201601f1916810167ffffffffffffffff81118282101715610f2357610f23610e76565b604052919050565b5f67ffffffffffffffff821115610f4457610f44610e76565b5060051b60200190565b5f8060408385031215610f5f575f80fd5b610f6883610e18565b915060208084013567ffffffffffffffff811115610f84575f80fd5b8401601f81018613610f94575f80fd5b8035610fa7610fa282610f2b565b610efa565b81815260059190911b82018301908381019088831115610fc5575f80fd5b928401925b82841015610fea57610fdb84610e18565b82529284019290840190610fca565b80955050505050509250929050565b5f60208284031215611009575f80fd5b61056582610e18565b5f8060408385031215611023575f80fd5b61102c83610e18565b915061103a60208401610e18565b90509250929050565b5f82601f830112611052575f80fd5b813567ffffffffffffffff81111561106c5761106c610e76565b61107f601f8201601f1916602001610efa565b818152846020838601011115611093575f80fd5b816020850160208301375f918101602001919091529392505050565b8035801515811461071b575f80fd5b8060070b81146110cc575f80fd5b50565b803561071b816110be565b5f82601f8301126110e9575f80fd5b813560206110f9610fa283610f2b565b82815260059290921b84018101918181019086841115611117575f80fd5b8286015b8481101561122057803567ffffffffffffffff8082111561113a575f80fd5b908801906040601f19838c038101821315611153575f80fd5b61115b610e8a565b8885013581528285013584811115611171575f80fd5b949094019360a0858e0383011215611187575f80fd5b61118f610eb3565b915061119c8986016110af565b82526111a9838601610e18565b89830152606080860135858111156111bf575f80fd5b6111cd8f8c838a0101611043565b85850152506080935083860135858111156111e6575f80fd5b6111f48f8c838a0101611043565b82850152505061120660a08601610e18565b92820192909252818801528552505091830191830161111b565b509695505050505050565b5f6060828403121561123b575f80fd5b6040516060810181811067ffffffffffffffff8211171561125e5761125e610e76565b604052905080823561126f816110be565b815261127d60208401610e18565b60208201526040830135611290816110be565b6040919091015292915050565b5f80604083850312156112ae575f80fd5b6112b783610e18565b9150602083013567ffffffffffffffff808211156112d3575f80fd5b9084019061016082870312156112e7575f80fd5b6112ef610ed6565b8235828111156112fd575f80fd5b61130988828601611043565b82525060208301358281111561131d575f80fd5b61132988828601611043565b60208301525061133b60408401610e18565b6040820152606083013582811115611351575f80fd5b61135d88828601611043565b60608301525061136f608084016110af565b608082015261138060a084016110cf565b60a082015261139160c084016110af565b60c082015260e0830135828111156113a7575f80fd5b6113b3888286016110da565b60e08301525061010091506113ca8783850161122b565b828201528093505050509250929050565b5f80604083850312156113ec575f80fd5b6113f583610e18565b9150602083013567ffffffffffffffff811115611410575f80fd5b61141c858286016110da565b9150509250929050565b5f82601f830112611435575f80fd5b81356020611445610fa283610f2b565b8083825260208201915060208460051b870101935086841115611466575f80fd5b602086015b8481101561122057803561147e816110be565b835291830191830161146b565b5f805f6060848603121561149d575f80fd5b6114a684610e18565b92506114b460208501610e18565b9150604084013567ffffffffffffffff8111156114cf575f80fd5b6114db86828701611426565b9150509250925092565b5f80604083850312156114f6575f80fd5b6114ff83610e18565b9150602083013567ffffffffffffffff81111561151a575f80fd5b61141c85828601611043565b5f5b83811015611540578181015183820152602001611528565b50505f910152565b5f815180845261155f816020860160208601611526565b601f01601f19169290920160200192915050565b828152604060208201525f61158b6040830184611548565b949350505050565b5f80608083850312156115a4575f80fd5b6115ad83610e18565b915061103a846020850161122b565b5f805f606084860312156115ce575f80fd5b6115d784610e18565b92506115e560208501610e18565b9150604084013590509250925092565b5f805f60608486031215611607575f80fd5b61161084610e18565b925061161e60208501610e18565b915061162c604085016110af565b90509250925092565b5f805f60608486031215611647575f80fd5b61165084610e18565b925060208401356114b4816110be565b5f805f60608486031215611672575f80fd5b61167b84610e18565b925061168960208501610e18565b91506040840135611699816110be565b809150509250925092565b5f82516116b5818460208701611526565b9190910192915050565b8051600381900b811461071b575f80fd5b5f602082840312156116e0575f80fd5b610565826116bf565b6001600160a01b0383168152604060208201525f61158b6040830184611548565b8215158152604060208201525f61158b6040830184611548565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015611771578551851683529483019491830191600101611753565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b8481101561183757601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a01526117f960e08a0186611548565b92860151898403603f1901858b01529294506118158584611548565b9501511660c0979097019690965250509884019892509083019060010161179a565b5090979650505050505050565b6001600160a01b0383168152604060208201525f825161016060408401526118706101a0840182611548565b90506020840151603f198085840301606086015261188e8383611548565b9250604086015191506118ac60808601836001600160a01b03169052565b60608601519150808584030160a08601526118c78383611548565b9250608086015191506118de60c086018315159052565b60a086015191506118f460e086018360070b9052565b60c0860151915061010061190b8187018415159052565b60e087015192508186850301610120870152611927848461177f565b908701518051600790810b61014089015260208201516001600160a01b03166101608901526040820151900b61018088015290935091506119659050565b50949350505050565b6001600160a01b0383168152604060208201525f61158b604083018461177f565b5f815180845260208085019450602084015f5b838110156119c157815160070b875295820195908201906001016119a2565b509495945050505050565b5f6001600160a01b038086168352808516602084015250606060408301526119f7606083018461198f565b95945050505050565b6001600160a01b0383168152608081016105656020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b6001600160a01b03841681528260070b6020820152606060408201525f6119f7606083018461198f565b5f8060408385031215611a7e575f80fd5b611a87836116bf565b91506020830151611a97816110be565b80915050925092905056fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa26469706673582212202da96f93cc2e178dd973a21f928bd28f62e0ead85ef55c0cd7deb839fb006f4564736f6c63430008180033", - "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610127575f3560e01c8063815228c0116100a9578063f25b12001161006e578063f25b12001461027c578063f52177ee1461028f578063f7be3425146102ba578063f848fec4146102cd578063fad0038a146102e0575f80fd5b8063815228c01461021d5780639b23d3d914610230578063a345f7bd14610243578063b26d33cb14610256578063df6c06f514610269575f80fd5b806336348de3116100ef57806336348de3146101b05780634d8f27c9146101c357806356af8403146101d6578063618dc65e146101e95780637d3e5da81461020a575f80fd5b806315dacbea1461012b5780632abf6c55146101565780632b256ec8146101775780632d73bb2e1461018a5780632eecbca31461019d575b5f80fd5b61013e610139366004610e2e565b6102f3565b60405160079190910b81526020015b60405180910390f35b610169610164366004610f4e565b6103e2565b60405190815260200161014d565b610169610185366004610ff9565b610427565b610169610198366004611012565b61049f565b61013e6101ab366004611012565b6104cd565b6101696101be36600461129d565b61050f565b61013e6101d13660046113db565b61051a565b6101696101e436600461148b565b610525565b6101fc6101f73660046114e5565b61056c565b60405161014d929190611573565b610169610218366004611012565b610683565b61016961022b366004611593565b61068e565b61013e61023e366004610e2e565b610699565b610169610251366004610ff9565b6106dd565b610169610264366004611012565b610720565b6101696102773660046115bc565b61072b565b61016961028a3660046115f5565b610737565b6102a261029d366004611635565b610743565b6040805192835260079190910b60208301520161014d565b6101696102c8366004610ff9565b610789565b6101696102db3660046115bc565b6107f8565b6101696102ee366004611660565b610804565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161037191906116a4565b5f604051808303815f865af19150503d805f81146103aa576040519150601f19603f3d011682016040523d82523d5f602084013e6103af565b606091505b5091509150816103c05760156103d4565b808060200190518101906103d491906116d0565b60030b979650505050505050565b5f6103ed8383610810565b90505f80516020611aa38339815191528160405161040d91815260200190565b60405180910390a160168114610421575f80fd5b92915050565b5f610431826108e7565b90505f80516020611aa38339815191528160405161045191815260200190565b60405180910390a160168114610465575f80fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b5f6104aa83836109bc565b60070b90505f80516020611aa38339815191528160405161040d91815260200190565b5f6104d883836109f1565b604051600782900b81529091505f80516020611aa38339815191529060200160405180910390a1600781900b601614610421575f80fd5b5f6103ed8383610a26565b5f6104d88383610a50565b5f610531848484610a7a565b90505f80516020611aa38339815191528160405161055191815260200190565b60405180910390a160168114610565575f80fd5b9392505050565b5f60605f806101676001600160a01b031663618dc65e60e01b87876040516024016105989291906116e9565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516105d691906116a4565b5f604051808303815f865af19150503d805f811461060f576040519150601f19603f3d011682016040523d82523d5f602084013e610614565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161064a92919061170a565b60405180910390a18161066d57601560405180602001604052805f815250610671565b6016815b60039190910b97909650945050505050565b5f6104aa8383610b54565b5f6103ed8383610b89565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610333565b5f6106e782610bb3565b90505f80516020611aa38339815191528160405161070791815260200190565b60405180910390a16016811461071b575f80fd5b919050565b5f6103ed8383610be0565b5f610531848484610c15565b5f610531848484610c51565b5f80610750858585610c8e565b60405182815291935091505f80516020611aa38339815191529060200160405180910390a160168214610781575f80fd5b935093915050565b5f61079382610d70565b90505f80516020611aa3833981519152816040516107b391815260200190565b60405180910390a1601681146107c7575f80fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d290602001610492565b5f610531848484610d9d565b5f610531848484610dd9565b5f805f6101676001600160a01b03166378b6391860e01b868660405160240161083a929190611724565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161087891906116a4565b5f604051808303815f865af19150503d805f81146108b1576040519150601f19603f3d011682016040523d82523d5f602084013e6108b6565b606091505b5091509150816108c75760156108db565b808060200190518101906108db91906116d0565b60030b95945050505050565b6040516001600160a01b03821660248201525f908190819061016790631f106b4b60e21b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161094e91906116a4565b5f604051808303815f865af19150503d805f8114610987576040519150601f19603f3d011682016040523d82523d5f602084013e61098c565b606091505b50915091508161099d5760156109b1565b808060200190518101906109b191906116d0565b60030b949350505050565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906352f9138760e01b9060640161083a565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063af99c63360e01b9060640161083a565b5f805f6101676001600160a01b0316637d305cfa60e01b868660405160240161083a929190611844565b5f805f6101676001600160a01b0316636fc3cbaf60e01b868660405160240161083a92919061196e565b5f805f6101676001600160a01b031663f7f38e2660e01b878787604051602401610aa6939291906119cc565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610ae491906116a4565b5f604051808303815f865af19150503d805f8114610b1d576040519150601f19603f3d011682016040523d82523d5f602084013e610b22565b606091505b509150915081610b33576015610b47565b80806020019051810190610b4791906116d0565b60030b9695505050505050565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906316e3e16160e21b9060640161083a565b5f805f6101676001600160a01b031663d27be6cd60e01b868660405160240161083a929190611a00565b6040516001600160a01b03821660248201525f908190819061016790637834fb8960e11b90604401610910565b6040516001600160a01b038381166024830152821660448201525f908190819061016790630132f29d60e31b9060640161083a565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b90608401610aa6565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b90608401610aa6565b5f805f806101676001600160a01b031663d6910d0660e01b888888604051602401610cbb93929190611a43565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610cf991906116a4565b5f604051808303815f865af19150503d805f8114610d32576040519150601f19603f3d011682016040523d82523d5f602084013e610d37565b606091505b509150915081610d495760155f610d5d565b80806020019051810190610d5d9190611a6d565b60039190910b9890975095505050505050565b6040516001600160a01b03821660248201525f908190819061016790633b3bff0f60e01b90604401610910565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b90608401610aa6565b6040516001600160a01b03848116602483015283166044820152600782900b60648201525f90819081906101679063efef57f960e01b90608401610aa6565b80356001600160a01b038116811461071b575f80fd5b5f805f8060808587031215610e41575f80fd5b610e4a85610e18565b9350610e5860208601610e18565b9250610e6660408601610e18565b9396929550929360600135925050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715610ead57610ead610e76565b60405290565b60405160a0810167ffffffffffffffff81118282101715610ead57610ead610e76565b604051610120810167ffffffffffffffff81118282101715610ead57610ead610e76565b604051601f8201601f1916810167ffffffffffffffff81118282101715610f2357610f23610e76565b604052919050565b5f67ffffffffffffffff821115610f4457610f44610e76565b5060051b60200190565b5f8060408385031215610f5f575f80fd5b610f6883610e18565b915060208084013567ffffffffffffffff811115610f84575f80fd5b8401601f81018613610f94575f80fd5b8035610fa7610fa282610f2b565b610efa565b81815260059190911b82018301908381019088831115610fc5575f80fd5b928401925b82841015610fea57610fdb84610e18565b82529284019290840190610fca565b80955050505050509250929050565b5f60208284031215611009575f80fd5b61056582610e18565b5f8060408385031215611023575f80fd5b61102c83610e18565b915061103a60208401610e18565b90509250929050565b5f82601f830112611052575f80fd5b813567ffffffffffffffff81111561106c5761106c610e76565b61107f601f8201601f1916602001610efa565b818152846020838601011115611093575f80fd5b816020850160208301375f918101602001919091529392505050565b8035801515811461071b575f80fd5b8060070b81146110cc575f80fd5b50565b803561071b816110be565b5f82601f8301126110e9575f80fd5b813560206110f9610fa283610f2b565b82815260059290921b84018101918181019086841115611117575f80fd5b8286015b8481101561122057803567ffffffffffffffff8082111561113a575f80fd5b908801906040601f19838c038101821315611153575f80fd5b61115b610e8a565b8885013581528285013584811115611171575f80fd5b949094019360a0858e0383011215611187575f80fd5b61118f610eb3565b915061119c8986016110af565b82526111a9838601610e18565b89830152606080860135858111156111bf575f80fd5b6111cd8f8c838a0101611043565b85850152506080935083860135858111156111e6575f80fd5b6111f48f8c838a0101611043565b82850152505061120660a08601610e18565b92820192909252818801528552505091830191830161111b565b509695505050505050565b5f6060828403121561123b575f80fd5b6040516060810181811067ffffffffffffffff8211171561125e5761125e610e76565b604052905080823561126f816110be565b815261127d60208401610e18565b60208201526040830135611290816110be565b6040919091015292915050565b5f80604083850312156112ae575f80fd5b6112b783610e18565b9150602083013567ffffffffffffffff808211156112d3575f80fd5b9084019061016082870312156112e7575f80fd5b6112ef610ed6565b8235828111156112fd575f80fd5b61130988828601611043565b82525060208301358281111561131d575f80fd5b61132988828601611043565b60208301525061133b60408401610e18565b6040820152606083013582811115611351575f80fd5b61135d88828601611043565b60608301525061136f608084016110af565b608082015261138060a084016110cf565b60a082015261139160c084016110af565b60c082015260e0830135828111156113a7575f80fd5b6113b3888286016110da565b60e08301525061010091506113ca8783850161122b565b828201528093505050509250929050565b5f80604083850312156113ec575f80fd5b6113f583610e18565b9150602083013567ffffffffffffffff811115611410575f80fd5b61141c858286016110da565b9150509250929050565b5f82601f830112611435575f80fd5b81356020611445610fa283610f2b565b8083825260208201915060208460051b870101935086841115611466575f80fd5b602086015b8481101561122057803561147e816110be565b835291830191830161146b565b5f805f6060848603121561149d575f80fd5b6114a684610e18565b92506114b460208501610e18565b9150604084013567ffffffffffffffff8111156114cf575f80fd5b6114db86828701611426565b9150509250925092565b5f80604083850312156114f6575f80fd5b6114ff83610e18565b9150602083013567ffffffffffffffff81111561151a575f80fd5b61141c85828601611043565b5f5b83811015611540578181015183820152602001611528565b50505f910152565b5f815180845261155f816020860160208601611526565b601f01601f19169290920160200192915050565b828152604060208201525f61158b6040830184611548565b949350505050565b5f80608083850312156115a4575f80fd5b6115ad83610e18565b915061103a846020850161122b565b5f805f606084860312156115ce575f80fd5b6115d784610e18565b92506115e560208501610e18565b9150604084013590509250925092565b5f805f60608486031215611607575f80fd5b61161084610e18565b925061161e60208501610e18565b915061162c604085016110af565b90509250925092565b5f805f60608486031215611647575f80fd5b61165084610e18565b925060208401356114b4816110be565b5f805f60608486031215611672575f80fd5b61167b84610e18565b925061168960208501610e18565b91506040840135611699816110be565b809150509250925092565b5f82516116b5818460208701611526565b9190910192915050565b8051600381900b811461071b575f80fd5b5f602082840312156116e0575f80fd5b610565826116bf565b6001600160a01b0383168152604060208201525f61158b6040830184611548565b8215158152604060208201525f61158b6040830184611548565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015611771578551851683529483019491830191600101611753565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b8481101561183757601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a01526117f960e08a0186611548565b92860151898403603f1901858b01529294506118158584611548565b9501511660c0979097019690965250509884019892509083019060010161179a565b5090979650505050505050565b6001600160a01b0383168152604060208201525f825161016060408401526118706101a0840182611548565b90506020840151603f198085840301606086015261188e8383611548565b9250604086015191506118ac60808601836001600160a01b03169052565b60608601519150808584030160a08601526118c78383611548565b9250608086015191506118de60c086018315159052565b60a086015191506118f460e086018360070b9052565b60c0860151915061010061190b8187018415159052565b60e087015192508186850301610120870152611927848461177f565b908701518051600790810b61014089015260208201516001600160a01b03166101608901526040820151900b61018088015290935091506119659050565b50949350505050565b6001600160a01b0383168152604060208201525f61158b604083018461177f565b5f815180845260208085019450602084015f5b838110156119c157815160070b875295820195908201906001016119a2565b509495945050505050565b5f6001600160a01b038086168352808516602084015250606060408301526119f7606083018461198f565b95945050505050565b6001600160a01b0383168152608081016105656020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b6001600160a01b03841681528260070b6020820152606060408201525f6119f7606083018461198f565b5f8060408385031215611a7e575f80fd5b611a87836116bf565b91506020830151611a97816110be565b80915050925092905056fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa26469706673582212202da96f93cc2e178dd973a21f928bd28f62e0ead85ef55c0cd7deb839fb006f4564736f6c63430008180033", + "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a556122ab806101235f395ff3fe608060405234801561000f575f80fd5b506004361061015b575f3560e01c8063815228c0116100c3578063df6c06f511610088578063f7be342511610063578063f7be342514610314578063f848fec414610327578063fad0038a1461033a575f80fd5b8063df6c06f5146102c3578063f25b1200146102d6578063f52177ee146102e9575f80fd5b8063815228c0146102645780639b23d3d914610277578063a345f7bd1461028a578063b26d33cb1461029d578063c1139a2e146102b0575f80fd5b806336348de31161012357806356af8403116100fe57806356af84031461021d578063618dc65e146102305780637d3e5da814610251575f80fd5b806336348de3146101e45780634504f884146101f75780634d8f27c91461020a575f80fd5b806315dacbea1461015f5780632abf6c551461018a5780632b256ec8146101ab5780632d73bb2e146101be5780632eecbca3146101d1575b5f80fd5b61017261016d3660046110d4565b61034d565b60405160079190910b81526020015b60405180910390f35b61019d610198366004611217565b61043c565b604051908152602001610181565b61019d6101b93660046112c2565b610481565b61019d6101cc3660046112db565b6104f9565b6101726101df3660046112db565b610527565b61019d6101f2366004611566565b610569565b61019d61020536600461176c565b610574565b6101726102183660046118ac565b6105e5565b61019d61022b36600461195c565b6105f0565b61024361023e3660046119b6565b610630565b604051610181929190611a44565b61019d61025f3660046112db565b610747565b61019d610272366004611a64565b610752565b6101726102853660046110d4565b61075d565b61019d6102983660046112c2565b6107a1565b61019d6102ab3660046112db565b6107e4565b61019d6102be366004611a8d565b6107ef565b61019d6102d1366004611bb9565b6107fb565b61019d6102e4366004611bf2565b610807565b6102fc6102f7366004611c32565b610813565b6040805192835260079190910b602083015201610181565b61019d6103223660046112c2565b610859565b61019d610335366004611bb9565b6108c8565b61019d610348366004611c5d565b6108d4565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516103cb9190611ca1565b5f604051808303815f865af19150503d805f8114610404576040519150601f19603f3d011682016040523d82523d5f602084013e610409565b606091505b50915091508161041a57601561042e565b8080602001905181019061042e9190611ccd565b60030b979650505050505050565b5f61044783836108e0565b90505f805160206122568339815191528160405161046791815260200190565b60405180910390a16016811461047b575f80fd5b92915050565b5f61048b826109b7565b90505f80516020612256833981519152816040516104ab91815260200190565b60405180910390a1601681146104bf575f80fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b5f6105048383610a8c565b60070b90505f805160206122568339815191528160405161046791815260200190565b5f6105328383610ac1565b604051600782900b81529091505f805160206122568339815191529060200160405180910390a1600781900b60161461047b575f80fd5b5f6104478383610af6565b5f610580848484610b20565b60070b90505f80516020612256833981519152816040516105a391815260200190565b60405180910390a1601681146105de576105bc81610bfa565b60405162461bcd60e51b81526004016105d59190611ce6565b60405180910390fd5b9392505050565b5f6105328383610c97565b5f6105fc848484610cc1565b90505f805160206122568339815191528160405161061c91815260200190565b60405180910390a1601681146105de575f80fd5b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161065c929190611cf8565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161069a9190611ca1565b5f604051808303815f865af19150503d805f81146106d3576040519150601f19603f3d011682016040523d82523d5f602084013e6106d8565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161070e929190611d19565b60405180910390a18161073157601560405180602001604052805f815250610735565b6016815b60039190910b97909650945050505050565b5f6105048383610ced565b5f6104478383610d22565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a40161038d565b5f6107ab82610d4c565b90505f80516020612256833981519152816040516107cb91815260200190565b60405180910390a1601681146107df575f80fd5b919050565b5f6104478383610d79565b5f610580848484610dae565b5f6105fc848484610dda565b5f6105fc848484610e16565b5f80610820858585610e53565b60405182815291935091505f805160206122568339815191529060200160405180910390a160168214610851575f80fd5b935093915050565b5f61086382610f35565b90505f805160206122568339815191528160405161088391815260200190565b60405180910390a160168114610897575f80fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d2906020016104ec565b5f6105fc848484610f62565b5f6105fc848484610f9e565b5f805f6101676001600160a01b03166378b6391860e01b868660405160240161090a929190611d33565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109489190611ca1565b5f604051808303815f865af19150503d805f8114610981576040519150601f19603f3d011682016040523d82523d5f602084013e610986565b606091505b5091509150816109975760156109ab565b808060200190518101906109ab9190611ccd565b60030b95945050505050565b6040516001600160a01b03821660248201525f908190819061016790631f106b4b60e21b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610a1e9190611ca1565b5f604051808303815f865af19150503d805f8114610a57576040519150601f19603f3d011682016040523d82523d5f602084013e610a5c565b606091505b509150915081610a6d576015610a81565b80806020019051810190610a819190611ccd565b60030b949350505050565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906352f9138760e01b9060640161090a565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063af99c63360e01b9060640161090a565b5f805f6101676001600160a01b0316637d305cfa60e01b868660405160240161090a929190611e46565b5f805f6101676001600160a01b031663d5f60c4760e01b878787604051602401610b4c93929190611fe7565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610b8a9190611ca1565b5f604051808303815f865af19150503d805f8114610bc3576040519150601f19603f3d011682016040523d82523d5f602084013e610bc8565b606091505b509150915081610bd9576015610bed565b80806020019051810190610bed9190611ccd565b60030b9695505050505050565b60605f610c0683610fdd565b60010190505f8167ffffffffffffffff811115610c2557610c2561111c565b6040519080825280601f01601f191660200182016040528015610c4f576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084610c5957509392505050565b5f805f6101676001600160a01b0316636fc3cbaf60e01b868660405160240161090a929190612092565b5f805f6101676001600160a01b031663f7f38e2660e01b878787604051602401610b4c939291906120e5565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906316e3e16160e21b9060640161090a565b5f805f6101676001600160a01b031663d27be6cd60e01b868660405160240161090a929190612119565b6040516001600160a01b03821660248201525f908190819061016790637834fb8960e11b906044016109e0565b6040516001600160a01b038381166024830152821660448201525f908190819061016790630132f29d60e31b9060640161090a565b5f805f6101676001600160a01b03166330727a2960e01b878787604051602401610b4c9392919061215c565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b90608401610b4c565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b90608401610b4c565b5f805f806101676001600160a01b031663d6910d0660e01b888888604051602401610e80939291906121f6565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610ebe9190611ca1565b5f604051808303815f865af19150503d805f8114610ef7576040519150601f19603f3d011682016040523d82523d5f602084013e610efc565b606091505b509150915081610f0e5760155f610f22565b80806020019051810190610f229190612220565b60039190910b9890975095505050505050565b6040516001600160a01b03821660248201525f908190819061016790633b3bff0f60e01b906044016109e0565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b90608401610b4c565b6040516001600160a01b03848116602483015283166044820152600782900b60648201525f90819081906101679063efef57f960e01b90608401610b4c565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611025577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310611051576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061106f57662386f26fc10000830492506010015b6305f5e1008310611087576305f5e100830492506008015b612710831061109b57612710830492506004015b606483106110ad576064830492506002015b600a831061047b5760010192915050565b80356001600160a01b03811681146107df575f80fd5b5f805f80608085870312156110e7575f80fd5b6110f0856110be565b93506110fe602086016110be565b925061110c604086016110be565b9396929550929360600135925050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156111535761115361111c565b60405290565b60405160a0810167ffffffffffffffff811182821017156111535761115361111c565b604051610120810167ffffffffffffffff811182821017156111535761115361111c565b60405160c0810167ffffffffffffffff811182821017156111535761115361111c565b604051601f8201601f1916810167ffffffffffffffff811182821017156111ec576111ec61111c565b604052919050565b5f67ffffffffffffffff82111561120d5761120d61111c565b5060051b60200190565b5f8060408385031215611228575f80fd5b611231836110be565b915060208084013567ffffffffffffffff81111561124d575f80fd5b8401601f8101861361125d575f80fd5b803561127061126b826111f4565b6111c3565b81815260059190911b8201830190838101908883111561128e575f80fd5b928401925b828410156112b3576112a4846110be565b82529284019290840190611293565b80955050505050509250929050565b5f602082840312156112d2575f80fd5b6105de826110be565b5f80604083850312156112ec575f80fd5b6112f5836110be565b9150611303602084016110be565b90509250929050565b5f82601f83011261131b575f80fd5b813567ffffffffffffffff8111156113355761133561111c565b611348601f8201601f19166020016111c3565b81815284602083860101111561135c575f80fd5b816020850160208301375f918101602001919091529392505050565b803580151581146107df575f80fd5b8060070b8114611395575f80fd5b50565b80356107df81611387565b5f82601f8301126113b2575f80fd5b813560206113c261126b836111f4565b82815260059290921b840181019181810190868411156113e0575f80fd5b8286015b848110156114e957803567ffffffffffffffff80821115611403575f80fd5b908801906040601f19838c03810182131561141c575f80fd5b611424611130565b888501358152828501358481111561143a575f80fd5b949094019360a0858e0383011215611450575f80fd5b611458611159565b9150611465898601611378565b82526114728386016110be565b8983015260608086013585811115611488575f80fd5b6114968f8c838a010161130c565b85850152506080935083860135858111156114af575f80fd5b6114bd8f8c838a010161130c565b8285015250506114cf60a086016110be565b9282019290925281880152855250509183019183016113e4565b509695505050505050565b5f60608284031215611504575f80fd5b6040516060810181811067ffffffffffffffff821117156115275761152761111c565b604052905080823561153881611387565b8152611546602084016110be565b6020820152604083013561155981611387565b6040919091015292915050565b5f8060408385031215611577575f80fd5b611580836110be565b9150602083013567ffffffffffffffff8082111561159c575f80fd5b9084019061016082870312156115b0575f80fd5b6115b861117c565b8235828111156115c6575f80fd5b6115d28882860161130c565b8252506020830135828111156115e6575f80fd5b6115f28882860161130c565b602083015250611604604084016110be565b604082015260608301358281111561161a575f80fd5b6116268882860161130c565b60608301525061163860808401611378565b608082015261164960a08401611398565b60a082015261165a60c08401611378565b60c082015260e083013582811115611670575f80fd5b61167c888286016113a3565b60e0830152506101009150611693878385016114f4565b828201528093505050509250929050565b5f82601f8301126116b3575f80fd5b813560206116c361126b836111f4565b82815260a092830285018201928282019190878511156116e1575f80fd5b8387015b8581101561175f5781818a0312156116fb575f80fd5b611703611159565b813561170e81611387565b815261171b8287016110be565b86820152604061172c818401611378565b90820152606061173d838201611378565b90820152608061174e8382016110be565b9082015284529284019281016116e5565b5090979650505050505050565b5f805f606080858703121561177f575f80fd5b611788856110be565b935060208086013567ffffffffffffffff808211156117a5575f80fd5b6117b189838a016116a4565b9550604091506040880135818111156117c8575f80fd5b88019050601f810189136117da575f80fd5b80356117e861126b826111f4565b81815260c0918202830185019185820191908c841115611806575f80fd5b938601935b8385101561189a5780858e031215611821575f80fd5b6118296111a0565b853561183481611387565b81528588013561184381611387565b818901528587013561185481611387565b818801528589013561186581611387565b818a01526080611876878201611378565b9082015260a06118878782016110be565b908201528352938401939186019161180b565b50809750505050505050509250925092565b5f80604083850312156118bd575f80fd5b6118c6836110be565b9150602083013567ffffffffffffffff8111156118e1575f80fd5b6118ed858286016113a3565b9150509250929050565b5f82601f830112611906575f80fd5b8135602061191661126b836111f4565b8083825260208201915060208460051b870101935086841115611937575f80fd5b602086015b848110156114e957803561194f81611387565b835291830191830161193c565b5f805f6060848603121561196e575f80fd5b611977846110be565b9250611985602085016110be565b9150604084013567ffffffffffffffff8111156119a0575f80fd5b6119ac868287016118f7565b9150509250925092565b5f80604083850312156119c7575f80fd5b6119d0836110be565b9150602083013567ffffffffffffffff8111156119eb575f80fd5b6118ed8582860161130c565b5f5b83811015611a115781810151838201526020016119f9565b50505f910152565b5f8151808452611a308160208601602086016119f7565b601f01601f19169290920160200192915050565b828152604060208201525f611a5c6040830184611a19565b949350505050565b5f8060808385031215611a75575f80fd5b611a7e836110be565b915061130384602085016114f4565b5f805f6060808587031215611aa0575f80fd5b611aa9856110be565b935060208086013567ffffffffffffffff80821115611ac6575f80fd5b611ad289838a016116a4565b955060409150604088013581811115611ae9575f80fd5b88019050601f81018913611afb575f80fd5b8035611b0961126b826111f4565b81815260c0918202830185019185820191908c841115611b27575f80fd5b938601935b8385101561189a5780858e031215611b42575f80fd5b611b4a6111a0565b8535611b5581611387565b815285880135611b6481611387565b8189015285870135611b7581611387565b81880152611b84868a016110be565b898201526080611b95818801611378565b9082015260a0611ba68782016110be565b9082015283529384019391860191611b2c565b5f805f60608486031215611bcb575f80fd5b611bd4846110be565b9250611be2602085016110be565b9150604084013590509250925092565b5f805f60608486031215611c04575f80fd5b611c0d846110be565b9250611c1b602085016110be565b9150611c2960408501611378565b90509250925092565b5f805f60608486031215611c44575f80fd5b611c4d846110be565b9250602084013561198581611387565b5f805f60608486031215611c6f575f80fd5b611c78846110be565b9250611c86602085016110be565b91506040840135611c9681611387565b809150509250925092565b5f8251611cb28184602087016119f7565b9190910192915050565b8051600381900b81146107df575f80fd5b5f60208284031215611cdd575f80fd5b6105de82611cbc565b602081525f6105de6020830184611a19565b6001600160a01b0383168152604060208201525f611a5c6040830184611a19565b8215158152604060208201525f611a5c6040830184611a19565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015611d80578551851683529483019491830191600101611d62565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b8481101561175f57601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a0152611e0860e08a0186611a19565b92860151898403603f1901858b0152929450611e248584611a19565b9501511660c09790970196909652505098840198925090830190600101611da9565b6001600160a01b0383168152604060208201525f82516101606040840152611e726101a0840182611a19565b90506020840151603f1980858403016060860152611e908383611a19565b925060408601519150611eae60808601836001600160a01b03169052565b60608601519150808584030160a0860152611ec98383611a19565b925060808601519150611ee060c086018315159052565b60a08601519150611ef660e086018360070b9052565b60c08601519150610100611f0d8187018415159052565b60e087015192508186850301610120870152611f298484611d8e565b908701518051600790810b61014089015260208201516001600160a01b03166101608901526040820151900b6101808801529093509150611f679050565b50949350505050565b5f815180845260208085019450602084015f5b83811015611fdc578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101611f83565b509495945050505050565b5f60606001600160a01b038087168452602060608186015261200c6060860188611f70565b8581036040878101919091528751808352838901928401905f5b818110156120815784518051600790810b855287820151810b8886015285820151810b8686015289820151900b8985015260808082015115159085015260a0908101518816908401529385019360c090920191600101612026565b50909b9a5050505050505050505050565b6001600160a01b0383168152604060208201525f611a5c6040830184611d8e565b5f815180845260208085019450602084015f5b83811015611fdc57815160070b875295820195908201906001016120c6565b5f6001600160a01b0380861683528085166020840152506060604083015261211060608301846120b3565b95945050505050565b6001600160a01b0383168152608081016105de6020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5f60606001600160a01b03808716845260206060818601526121816060860188611f70565b8581036040878101919091528751808352838901928401905f5b818110156120815784518051600790810b855287820151810b8886015285820151900b858501528881015188168985015260808082015115159085015260a0908101518816908401529385019360c09092019160010161219b565b6001600160a01b03841681528260070b6020820152606060408201525f61211060608301846120b3565b5f8060408385031215612231575f80fd5b61223a83611cbc565b9150602083015161224a81611387565b80915050925092905056fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa26469706673582212201e7bb052db93430e6b16285b3d70717476b153633d04496b598618dfc91621d564736f6c63430008180033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061015b575f3560e01c8063815228c0116100c3578063df6c06f511610088578063f7be342511610063578063f7be342514610314578063f848fec414610327578063fad0038a1461033a575f80fd5b8063df6c06f5146102c3578063f25b1200146102d6578063f52177ee146102e9575f80fd5b8063815228c0146102645780639b23d3d914610277578063a345f7bd1461028a578063b26d33cb1461029d578063c1139a2e146102b0575f80fd5b806336348de31161012357806356af8403116100fe57806356af84031461021d578063618dc65e146102305780637d3e5da814610251575f80fd5b806336348de3146101e45780634504f884146101f75780634d8f27c91461020a575f80fd5b806315dacbea1461015f5780632abf6c551461018a5780632b256ec8146101ab5780632d73bb2e146101be5780632eecbca3146101d1575b5f80fd5b61017261016d3660046110d4565b61034d565b60405160079190910b81526020015b60405180910390f35b61019d610198366004611217565b61043c565b604051908152602001610181565b61019d6101b93660046112c2565b610481565b61019d6101cc3660046112db565b6104f9565b6101726101df3660046112db565b610527565b61019d6101f2366004611566565b610569565b61019d61020536600461176c565b610574565b6101726102183660046118ac565b6105e5565b61019d61022b36600461195c565b6105f0565b61024361023e3660046119b6565b610630565b604051610181929190611a44565b61019d61025f3660046112db565b610747565b61019d610272366004611a64565b610752565b6101726102853660046110d4565b61075d565b61019d6102983660046112c2565b6107a1565b61019d6102ab3660046112db565b6107e4565b61019d6102be366004611a8d565b6107ef565b61019d6102d1366004611bb9565b6107fb565b61019d6102e4366004611bf2565b610807565b6102fc6102f7366004611c32565b610813565b6040805192835260079190910b602083015201610181565b61019d6103223660046112c2565b610859565b61019d610335366004611bb9565b6108c8565b61019d610348366004611c5d565b6108d4565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516103cb9190611ca1565b5f604051808303815f865af19150503d805f8114610404576040519150601f19603f3d011682016040523d82523d5f602084013e610409565b606091505b50915091508161041a57601561042e565b8080602001905181019061042e9190611ccd565b60030b979650505050505050565b5f61044783836108e0565b90505f805160206122568339815191528160405161046791815260200190565b60405180910390a16016811461047b575f80fd5b92915050565b5f61048b826109b7565b90505f80516020612256833981519152816040516104ab91815260200190565b60405180910390a1601681146104bf575f80fd5b604051600181527f0c9c765845f4d139956bb8fc8decb2eec6093c9c608b809641b16054b29f0e13906020015b60405180910390a1919050565b5f6105048383610a8c565b60070b90505f805160206122568339815191528160405161046791815260200190565b5f6105328383610ac1565b604051600782900b81529091505f805160206122568339815191529060200160405180910390a1600781900b60161461047b575f80fd5b5f6104478383610af6565b5f610580848484610b20565b60070b90505f80516020612256833981519152816040516105a391815260200190565b60405180910390a1601681146105de576105bc81610bfa565b60405162461bcd60e51b81526004016105d59190611ce6565b60405180910390fd5b9392505050565b5f6105328383610c97565b5f6105fc848484610cc1565b90505f805160206122568339815191528160405161061c91815260200190565b60405180910390a1601681146105de575f80fd5b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161065c929190611cf8565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161069a9190611ca1565b5f604051808303815f865af19150503d805f81146106d3576040519150601f19603f3d011682016040523d82523d5f602084013e6106d8565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161070e929190611d19565b60405180910390a18161073157601560405180602001604052805f815250610735565b6016815b60039190910b97909650945050505050565b5f6105048383610ced565b5f6104478383610d22565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a40161038d565b5f6107ab82610d4c565b90505f80516020612256833981519152816040516107cb91815260200190565b60405180910390a1601681146107df575f80fd5b919050565b5f6104478383610d79565b5f610580848484610dae565b5f6105fc848484610dda565b5f6105fc848484610e16565b5f80610820858585610e53565b60405182815291935091505f805160206122568339815191529060200160405180910390a160168214610851575f80fd5b935093915050565b5f61086382610f35565b90505f805160206122568339815191528160405161088391815260200190565b60405180910390a160168114610897575f80fd5b604051600181527f319ab7084208e4afa38c6e6ff7aea9587439f2e4700746f4c7d425fea17426d2906020016104ec565b5f6105fc848484610f62565b5f6105fc848484610f9e565b5f805f6101676001600160a01b03166378b6391860e01b868660405160240161090a929190611d33565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516109489190611ca1565b5f604051808303815f865af19150503d805f8114610981576040519150601f19603f3d011682016040523d82523d5f602084013e610986565b606091505b5091509150816109975760156109ab565b808060200190518101906109ab9190611ccd565b60030b95945050505050565b6040516001600160a01b03821660248201525f908190819061016790631f106b4b60e21b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610a1e9190611ca1565b5f604051808303815f865af19150503d805f8114610a57576040519150601f19603f3d011682016040523d82523d5f602084013e610a5c565b606091505b509150915081610a6d576015610a81565b80806020019051810190610a819190611ccd565b60030b949350505050565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906352f9138760e01b9060640161090a565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063af99c63360e01b9060640161090a565b5f805f6101676001600160a01b0316637d305cfa60e01b868660405160240161090a929190611e46565b5f805f6101676001600160a01b031663d5f60c4760e01b878787604051602401610b4c93929190611fe7565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610b8a9190611ca1565b5f604051808303815f865af19150503d805f8114610bc3576040519150601f19603f3d011682016040523d82523d5f602084013e610bc8565b606091505b509150915081610bd9576015610bed565b80806020019051810190610bed9190611ccd565b60030b9695505050505050565b60605f610c0683610fdd565b60010190505f8167ffffffffffffffff811115610c2557610c2561111c565b6040519080825280601f01601f191660200182016040528015610c4f576020820181803683370190505b5090508181016020015b5f19017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084610c5957509392505050565b5f805f6101676001600160a01b0316636fc3cbaf60e01b868660405160240161090a929190612092565b5f805f6101676001600160a01b031663f7f38e2660e01b878787604051602401610b4c939291906120e5565b6040516001600160a01b038381166024830152821660448201525f9081908190610167906316e3e16160e21b9060640161090a565b5f805f6101676001600160a01b031663d27be6cd60e01b868660405160240161090a929190612119565b6040516001600160a01b03821660248201525f908190819061016790637834fb8960e11b906044016109e0565b6040516001600160a01b038381166024830152821660448201525f908190819061016790630132f29d60e31b9060640161090a565b5f805f6101676001600160a01b03166330727a2960e01b878787604051602401610b4c9392919061215c565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b90608401610b4c565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b90608401610b4c565b5f805f806101676001600160a01b031663d6910d0660e01b888888604051602401610e80939291906121f6565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051610ebe9190611ca1565b5f604051808303815f865af19150503d805f8114610ef7576040519150601f19603f3d011682016040523d82523d5f602084013e610efc565b606091505b509150915081610f0e5760155f610f22565b80806020019051810190610f229190612220565b60039190910b9890975095505050505050565b6040516001600160a01b03821660248201525f908190819061016790633b3bff0f60e01b906044016109e0565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b90608401610b4c565b6040516001600160a01b03848116602483015283166044820152600782900b60648201525f90819081906101679063efef57f960e01b90608401610b4c565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611025577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310611051576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061106f57662386f26fc10000830492506010015b6305f5e1008310611087576305f5e100830492506008015b612710831061109b57612710830492506004015b606483106110ad576064830492506002015b600a831061047b5760010192915050565b80356001600160a01b03811681146107df575f80fd5b5f805f80608085870312156110e7575f80fd5b6110f0856110be565b93506110fe602086016110be565b925061110c604086016110be565b9396929550929360600135925050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156111535761115361111c565b60405290565b60405160a0810167ffffffffffffffff811182821017156111535761115361111c565b604051610120810167ffffffffffffffff811182821017156111535761115361111c565b60405160c0810167ffffffffffffffff811182821017156111535761115361111c565b604051601f8201601f1916810167ffffffffffffffff811182821017156111ec576111ec61111c565b604052919050565b5f67ffffffffffffffff82111561120d5761120d61111c565b5060051b60200190565b5f8060408385031215611228575f80fd5b611231836110be565b915060208084013567ffffffffffffffff81111561124d575f80fd5b8401601f8101861361125d575f80fd5b803561127061126b826111f4565b6111c3565b81815260059190911b8201830190838101908883111561128e575f80fd5b928401925b828410156112b3576112a4846110be565b82529284019290840190611293565b80955050505050509250929050565b5f602082840312156112d2575f80fd5b6105de826110be565b5f80604083850312156112ec575f80fd5b6112f5836110be565b9150611303602084016110be565b90509250929050565b5f82601f83011261131b575f80fd5b813567ffffffffffffffff8111156113355761133561111c565b611348601f8201601f19166020016111c3565b81815284602083860101111561135c575f80fd5b816020850160208301375f918101602001919091529392505050565b803580151581146107df575f80fd5b8060070b8114611395575f80fd5b50565b80356107df81611387565b5f82601f8301126113b2575f80fd5b813560206113c261126b836111f4565b82815260059290921b840181019181810190868411156113e0575f80fd5b8286015b848110156114e957803567ffffffffffffffff80821115611403575f80fd5b908801906040601f19838c03810182131561141c575f80fd5b611424611130565b888501358152828501358481111561143a575f80fd5b949094019360a0858e0383011215611450575f80fd5b611458611159565b9150611465898601611378565b82526114728386016110be565b8983015260608086013585811115611488575f80fd5b6114968f8c838a010161130c565b85850152506080935083860135858111156114af575f80fd5b6114bd8f8c838a010161130c565b8285015250506114cf60a086016110be565b9282019290925281880152855250509183019183016113e4565b509695505050505050565b5f60608284031215611504575f80fd5b6040516060810181811067ffffffffffffffff821117156115275761152761111c565b604052905080823561153881611387565b8152611546602084016110be565b6020820152604083013561155981611387565b6040919091015292915050565b5f8060408385031215611577575f80fd5b611580836110be565b9150602083013567ffffffffffffffff8082111561159c575f80fd5b9084019061016082870312156115b0575f80fd5b6115b861117c565b8235828111156115c6575f80fd5b6115d28882860161130c565b8252506020830135828111156115e6575f80fd5b6115f28882860161130c565b602083015250611604604084016110be565b604082015260608301358281111561161a575f80fd5b6116268882860161130c565b60608301525061163860808401611378565b608082015261164960a08401611398565b60a082015261165a60c08401611378565b60c082015260e083013582811115611670575f80fd5b61167c888286016113a3565b60e0830152506101009150611693878385016114f4565b828201528093505050509250929050565b5f82601f8301126116b3575f80fd5b813560206116c361126b836111f4565b82815260a092830285018201928282019190878511156116e1575f80fd5b8387015b8581101561175f5781818a0312156116fb575f80fd5b611703611159565b813561170e81611387565b815261171b8287016110be565b86820152604061172c818401611378565b90820152606061173d838201611378565b90820152608061174e8382016110be565b9082015284529284019281016116e5565b5090979650505050505050565b5f805f606080858703121561177f575f80fd5b611788856110be565b935060208086013567ffffffffffffffff808211156117a5575f80fd5b6117b189838a016116a4565b9550604091506040880135818111156117c8575f80fd5b88019050601f810189136117da575f80fd5b80356117e861126b826111f4565b81815260c0918202830185019185820191908c841115611806575f80fd5b938601935b8385101561189a5780858e031215611821575f80fd5b6118296111a0565b853561183481611387565b81528588013561184381611387565b818901528587013561185481611387565b818801528589013561186581611387565b818a01526080611876878201611378565b9082015260a06118878782016110be565b908201528352938401939186019161180b565b50809750505050505050509250925092565b5f80604083850312156118bd575f80fd5b6118c6836110be565b9150602083013567ffffffffffffffff8111156118e1575f80fd5b6118ed858286016113a3565b9150509250929050565b5f82601f830112611906575f80fd5b8135602061191661126b836111f4565b8083825260208201915060208460051b870101935086841115611937575f80fd5b602086015b848110156114e957803561194f81611387565b835291830191830161193c565b5f805f6060848603121561196e575f80fd5b611977846110be565b9250611985602085016110be565b9150604084013567ffffffffffffffff8111156119a0575f80fd5b6119ac868287016118f7565b9150509250925092565b5f80604083850312156119c7575f80fd5b6119d0836110be565b9150602083013567ffffffffffffffff8111156119eb575f80fd5b6118ed8582860161130c565b5f5b83811015611a115781810151838201526020016119f9565b50505f910152565b5f8151808452611a308160208601602086016119f7565b601f01601f19169290920160200192915050565b828152604060208201525f611a5c6040830184611a19565b949350505050565b5f8060808385031215611a75575f80fd5b611a7e836110be565b915061130384602085016114f4565b5f805f6060808587031215611aa0575f80fd5b611aa9856110be565b935060208086013567ffffffffffffffff80821115611ac6575f80fd5b611ad289838a016116a4565b955060409150604088013581811115611ae9575f80fd5b88019050601f81018913611afb575f80fd5b8035611b0961126b826111f4565b81815260c0918202830185019185820191908c841115611b27575f80fd5b938601935b8385101561189a5780858e031215611b42575f80fd5b611b4a6111a0565b8535611b5581611387565b815285880135611b6481611387565b8189015285870135611b7581611387565b81880152611b84868a016110be565b898201526080611b95818801611378565b9082015260a0611ba68782016110be565b9082015283529384019391860191611b2c565b5f805f60608486031215611bcb575f80fd5b611bd4846110be565b9250611be2602085016110be565b9150604084013590509250925092565b5f805f60608486031215611c04575f80fd5b611c0d846110be565b9250611c1b602085016110be565b9150611c2960408501611378565b90509250925092565b5f805f60608486031215611c44575f80fd5b611c4d846110be565b9250602084013561198581611387565b5f805f60608486031215611c6f575f80fd5b611c78846110be565b9250611c86602085016110be565b91506040840135611c9681611387565b809150509250925092565b5f8251611cb28184602087016119f7565b9190910192915050565b8051600381900b81146107df575f80fd5b5f60208284031215611cdd575f80fd5b6105de82611cbc565b602081525f6105de6020830184611a19565b6001600160a01b0383168152604060208201525f611a5c6040830184611a19565b8215158152604060208201525f611a5c6040830184611a19565b5f604082016001600160a01b0380861684526020604060208601528286518085526060870191506020880194505f5b81811015611d80578551851683529483019491830191600101611d62565b509098975050505050505050565b5f82825180855260208086019550808260051b8401018186015f5b8481101561175f57601f198684030189528151604081518552858201519150808686015281511515818601528582015160606001600160a01b038083168289015283850151935060a09250608083818a0152611e0860e08a0186611a19565b92860151898403603f1901858b0152929450611e248584611a19565b9501511660c09790970196909652505098840198925090830190600101611da9565b6001600160a01b0383168152604060208201525f82516101606040840152611e726101a0840182611a19565b90506020840151603f1980858403016060860152611e908383611a19565b925060408601519150611eae60808601836001600160a01b03169052565b60608601519150808584030160a0860152611ec98383611a19565b925060808601519150611ee060c086018315159052565b60a08601519150611ef660e086018360070b9052565b60c08601519150610100611f0d8187018415159052565b60e087015192508186850301610120870152611f298484611d8e565b908701518051600790810b61014089015260208201516001600160a01b03166101608901526040820151900b6101808801529093509150611f679050565b50949350505050565b5f815180845260208085019450602084015f5b83811015611fdc578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101611f83565b509495945050505050565b5f60606001600160a01b038087168452602060608186015261200c6060860188611f70565b8581036040878101919091528751808352838901928401905f5b818110156120815784518051600790810b855287820151810b8886015285820151810b8686015289820151900b8985015260808082015115159085015260a0908101518816908401529385019360c090920191600101612026565b50909b9a5050505050505050505050565b6001600160a01b0383168152604060208201525f611a5c6040830184611d8e565b5f815180845260208085019450602084015f5b83811015611fdc57815160070b875295820195908201906001016120c6565b5f6001600160a01b0380861683528085166020840152506060604083015261211060608301846120b3565b95945050505050565b6001600160a01b0383168152608081016105de6020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5f60606001600160a01b03808716845260206060818601526121816060860188611f70565b8581036040878101919091528751808352838901928401905f5b818110156120815784518051600790810b855287820151810b8886015285820151900b858501528881015188168985015260808082015115159085015260a0908101518816908401529385019360c09092019160010161219b565b6001600160a01b03841681528260070b6020820152606060408201525f61211060608301846120b3565b5f8060408385031215612231575f80fd5b61223a83611cbc565b9150602083015161224a81611387565b80915050925092905056fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa26469706673582212201e7bb052db93430e6b16285b3d70717476b153633d04496b598618dfc91621d564736f6c63430008180033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-query/TokenQueryContract.sol/TokenQueryContract.json b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-query/TokenQueryContract.sol/TokenQueryContract.json index efac09fb8..f7cc5a7f8 100644 --- a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-query/TokenQueryContract.sol/TokenQueryContract.json +++ b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-query/TokenQueryContract.sol/TokenQueryContract.json @@ -2559,8 +2559,8 @@ "type": "function" } ], - "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a55612dc0806101235f395ff3fe608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063618dc65e1161009e5780638c99ef5d1161006e5780638c99ef5d146102d05780639b23d3d9146102fd578063a3ad5b5514610310578063c0b19b6d14610323578063f2f38a7414610344575f80fd5b8063618dc65e1461026857806369837dc2146102895780636a4dde21146102aa57806386f88d88146102bd575f80fd5b80633eed2c39116100e45780633eed2c39146101b95780634cbdb37b146101cc5780635a5e6c31146101ed5780635b9076b7146102155780635d2c5bad14610238575f80fd5b806313c05dd81461011557806315dacbea146101425780631955de0b1461016857806319db44b614610189575b5f80fd5b6101286101233660046118dd565b610365565b604080519283529015156020830152015b60405180910390f35b610155610150366004611925565b6103e0565b60405160079190910b8152602001610139565b61017b610176366004611973565b6104cf565b604051610139929190611a54565b61019c610197366004611973565b61057b565b604080519283526001600160a01b03909116602083015201610139565b6101286101c7366004611a77565b6105f1565b6101df6101da366004611aa7565b610668565b604051610139929190611f09565b6102006101fb3660046118dd565b6106db565b60408051928352602083019190915201610139565b610228610223366004611a77565b610749565b6040516101399493929190611f21565b61024b610246366004611a77565b6107d8565b6040805160079390930b835260039190910b602083015201610139565b61027b61027636600461206c565b610850565b6040516101399291906120f9565b61029c610297366004611a77565b610967565b60405161013992919061213c565b6101286102b8366004612154565b6109d9565b6101286102cb366004611a77565b610a4d565b6102e36102de366004611a77565b610abb565b6040805160079390930b8352901515602083015201610139565b61015561030b366004611925565b610b31565b6102e361031e366004612154565b610b75565b610336610331366004611a77565b610bec565b604051610139929190612180565b610357610352366004611a77565b610c70565b6040516101399291906121ba565b5f80610372858585610ce2565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146103a3575f80fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161045e91906121d2565b5f604051808303815f865af19150503d805f8114610497576040519150601f19603f3d011682016040523d82523d5f602084013e61049c565b606091505b5091509150816104ad5760156104c1565b808060200190518101906104c19190612203565b60030b979650505050505050565b6040805160a0810182525f80825260208201819052606092820183905282820192909252608081018290526105048484610dc2565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461053d575f80fd5b7faed084fbdf29b6ba2242463299d7270f64e0f8ced16013cfff249856bd8871578160405161056c919061221c565b60405180910390a19250929050565b5f806105878484610eeb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146105b8575f80fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb9060200161056c565b5f806105fc83610fac565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a16016821461062d575f80fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b5f6106716117bb565b61067b848461108a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146106ac575f80fd5b7f91ccf16c022fe2d397abee975516433182ab8f781d4ef14b66cc732526e66dcf8160405161056c919061222e565b5f806106e885858561115e565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610719575f80fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c8906020016103d0565b5f60608060606107588561122b565b604051600785900b8152939750919550935091505f80516020612d6b8339815191529060200160405180910390a1600784900b601614610796575f80fd5b7f2fc15414e589a7221dbee977ae9650a8990a7544fd1b3ae3ae62f4797f412a998383836040516107c993929190612240565b60405180910390a19193509193565b5f806107e38361130d565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461081c575f80fd5b604051600382900b81527f182137409609594f2b12128230091c673507ea4cab315d59415d5e3f8c301ad59060200161065b565b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161087c929190612278565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108ba91906121d2565b5f604051808303815f865af19150503d805f81146108f3576040519150601f19603f3d011682016040523d82523d5f602084013e6108f8565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161092e929190612299565b60405180910390a18161095157601560405180602001604052805f815250610955565b6016815b60039190910b97909650945050505050565b5f6109706117f5565b610979836113cb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146109aa575f80fd5b7f4ef7d8101cfcfd8272047933834c75def485d9965aef926f86f237d4e61ef6388160405161065b91906122b3565b5f806109e58484611495565b60405160079290920b808352935091505f80516020612d6b8339815191529060200160405180910390a160168214610a1b575f80fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e9060200161056c565b5f80610a588361156a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610a89575f80fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd9060200161065b565b5f80610ac683611599565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610aff575f80fd5b60405181151581527f5080c42cc33acbcea410fa6eaa925bd878674825501981184fdd53749f8478a89060200161065b565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610420565b5f80610b8184846115c8565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610bba575f80fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f9060200161056c565b604080516060810182525f80825260208201819052918101829052610c10836115ff565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610c41575f80fd5b7ffed17041c1dbab1a630961a1f2d469641f421ee8a8b0f717d6f840c75e4593338160405161065b91906122c5565b5f610c79611814565b610c82836116f1565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610cb3575f80fd5b7fd1a813e1ab0917de7318f3003f23664aed447e65204cf1e19c2c806e591c851f8160405161065b91906122ff565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663f49f40db60e01b17905290515f9182918291829161016791610d4b916121d2565b5f604051808303815f865af19150503d805f8114610d84576040519150601f19603f3d011682016040523d82523d5f602084013e610d89565b606091505b509150915081610d9b5760155f610daf565b80806020019051810190610daf9190612320565b60039190910b9890975095505050505050565b6040805160a0810182525f80825260208083018290526060838501819052808401526080830182905283516001600160a01b03871660248201526044808201879052855180830390910181526064909101855290810180516001600160e01b0316631e26e99760e11b179052925190928391829161016791610e4491906121d2565b5f604051808303815f865af19150503d805f8114610e7d576040519150601f19603f3d011682016040523d82523d5f602084013e610e82565b606091505b5091509150610eca6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b82610ed757601581610daf565b81806020019051810190610daf9190612440565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03166304c791b360e11b17905290515f9182918291829161016791610f48916121d2565b5f604051808303815f865af19150503d805f8114610f81576040519150601f19603f3d011682016040523d82523d5f602084013e610f86565b606091505b509150915081610f985760155f610955565b80806020019051810190610955919061248b565b6040516001600160a01b03821660248201525f908190819081906101679063a7daa18d60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161101591906121d2565b5f604051808303815f865af19150503d805f811461104e576040519150601f19603f3d011682016040523d82523d5f602084013e611053565b606091505b5091509150816110655760155f611079565b808060200190518101906110799190612320565b60039190910b969095509350505050565b5f6110936117bb565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b031663050fc3b560e31b17905290515f918291610167916110f2916121d2565b5f604051808303815f865af19150503d805f811461112b576040519150601f19603f3d011682016040523d82523d5f602084013e611130565b606091505b509150915061113d6117bb565b8261114a57601581610daf565b81806020019051810190610daf9190612aad565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663927da10560e01b17905290515f91829182918291610167916111c7916121d2565b5f604051808303815f865af19150503d805f8114611200576040519150601f19603f3d011682016040523d82523d5f602084013e611205565b606091505b5091509150816112175760155f610daf565b80806020019051810190610daf9190612b8f565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316630573b08d60e51b17905290515f91606091829182918591829161016791611289916121d2565b5f604051808303815f865af19150503d805f81146112c2576040519150601f19603f3d011682016040523d82523d5f602084013e6112c7565b606091505b50915091506060806060846112e05760158383836112f4565b838060200190518101906112f49190612bb9565b60039390930b9d919c509a509098509650505050505050565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03166393272baf60e01b17905290515f9182918291829161016791611366916121d2565b5f604051808303815f865af19150503d805f811461139f576040519150601f19603f3d011682016040523d82523d5f602084013e6113a4565b606091505b5091509150816113b75760155f19611079565b808060200190518101906110799190612c4c565b5f6113d46117f5565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316633f28a19b60e01b17905290515f91829161016791611429916121d2565b5f604051808303815f865af19150503d805f8114611462576040519150601f19603f3d011682016040523d82523d5f602084013e611467565b606091505b50915091506114746117f5565b8261148157601581610955565b818060200190518101906109559190612c74565b6040516001600160a01b038381166024830152821660448201525f90819081908190610167906346de0fb160e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161150691906121d2565b5f604051808303815f865af19150503d805f811461153f576040519150601f19603f3d011682016040523d82523d5f602084013e611544565b606091505b5091509150816115565760155f610955565b808060200190518101906109559190612320565b6040516001600160a01b03821660248201525f908190819081906101679063335e04c160e01b90604401610fd7565b6040516001600160a01b03821660248201525f90819081908190610167906319f3736160e01b90604401610fd7565b6040516001600160a01b038381166024830152821660448201525f9081908190819061016790633cb0c7fd60e21b906064016114c8565b604080516060810182525f808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b17905292519092839182916101679161167091906121d2565b5f604051808303815f865af19150503d805f81146116a9576040519150601f19603f3d011682016040523d82523d5f602084013e6116ae565b606091505b50604080516060810182525f80825260208201819052918101919091529193509150826116dd57601581610955565b818060200190518101906109559190612d00565b5f6116fa611814565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316631f69565f60e01b17905290515f9182916101679161174f916121d2565b5f604051808303815f865af19150503d805f8114611788576040519150601f19603f3d011682016040523d82523d5f602084013e61178d565b606091505b509150915061179a611814565b826117a757601581610955565b818060200190518101906109559190612d29565b6040518060c001604052806117ce611814565b81525f60208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280611808611814565b81525f60209091015290565b60408051610240810182526060610120820181815261014083018290525f610160840181905261018084018390526101a084018190526101c084018190526101e08401819052610200840183905284519283018552808352602083018190529382019390935261022082015290819081526020015f60070b81526020015f151581526020015f151581526020015f15158152602001606081526020016060815260200160608152602001606081525090565b6001600160a01b03811681146118da575f80fd5b50565b5f805f606084860312156118ef575f80fd5b83356118fa816118c6565b9250602084013561190a816118c6565b9150604084013561191a816118c6565b809150509250925092565b5f805f8060808587031215611938575f80fd5b8435611943816118c6565b93506020850135611953816118c6565b92506040850135611963816118c6565b9396929550929360600135925050565b5f8060408385031215611984575f80fd5b823561198f816118c6565b946020939093013593505050565b5f5b838110156119b757818101518382015260200161199f565b50505f910152565b5f81518084526119d681602086016020860161199d565b601f01601f19169290920160200192915050565b8051151582525f60208201516001600160a01b0380821660208601526040840151915060a06040860152611a2160a08601836119bf565b915060608401518583036060870152611a3a83826119bf565b925050806080850151166080860152508091505092915050565b8260070b8152604060208201525f611a6f60408301846119ea565b949350505050565b5f60208284031215611a87575f80fd5b8135611a92816118c6565b9392505050565b8060070b81146118da575f80fd5b5f8060408385031215611ab8575f80fd5b8235611ac3816118c6565b91506020830135611ad381611a99565b809150509250929050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611b3b57858303601f190189528151805184528401516040858501819052611b27818601836119ea565b9a86019a9450505090830190600101611af9565b5090979650505050505050565b5f6101608251818552611b5d828601826119bf565b91505060208301518482036020860152611b7782826119bf565b9150506040830151611b9460408601826001600160a01b03169052565b5060608301518482036060860152611bac82826119bf565b9150506080830151611bc2608086018215159052565b5060a0830151611bd760a086018260070b9052565b5060c0830151611beb60c086018215159052565b5060e083015184820360e0860152611c038282611ade565b91505061010080840151611c3f82870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b83811015611cb5578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101611c5c565b509495945050505050565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a0152604080830151820b908a015260608083015190910b9089015260808082015115159089015260a0908101516001600160a01b03169088015260c09096019590820190600101611cd3565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a015260408083015190910b908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c09096019590820190600101611d4d565b5f6101208251818552611dcd82860182611b48565b9150506020830151611de4602086018260070b9052565b506040830151611df8604086018215159052565b506060830151611e0c606086018215159052565b506080830151611e20608086018215159052565b5060a083015184820360a0860152611e388282611c49565b91505060c083015184820360c0860152611e528282611cc0565b91505060e083015184820360e0860152611e6c8282611d3a565b9150506101008084015185830382870152611e8783826119bf565b9695505050505050565b5f815160c08452611ea560c0850182611db8565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b6060870152608085015191508583036080870152611eef83836119bf565b92508060a08601511660a087015250508091505092915050565b828152604060208201525f611a6f6040830184611e91565b8460070b8152608060208201525f611f3c6080830186611c49565b8281036040840152611f4e8186611cc0565b90508281036060840152611f628185611d3a565b979650505050505050565b634e487b7160e01b5f52604160045260245ffd5b60405160a0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405290565b6040805190810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051610120810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405160c0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051601f8201601f1916810167ffffffffffffffff8111828210171561203d5761203d611f6d565b604052919050565b5f67ffffffffffffffff82111561205e5761205e611f6d565b50601f01601f191660200190565b5f806040838503121561207d575f80fd5b8235612088816118c6565b9150602083013567ffffffffffffffff8111156120a3575f80fd5b8301601f810185136120b3575f80fd5b80356120c66120c182612045565b612014565b8181528660208385010111156120da575f80fd5b816020840160208301375f602083830101528093505050509250929050565b828152604060208201525f611a6f60408301846119bf565b5f8151604084526121256040850182611db8565b60209384015160030b949093019390935250919050565b828152604060208201525f611a6f6040830184612111565b5f8060408385031215612165575f80fd5b8235612170816118c6565b91506020830135611ad3816118c6565b82815260808101611a926020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b828152604060208201525f611a6f6040830184611db8565b5f82516121e381846020870161199d565b9190910192915050565b8051600381900b81146121fe575f80fd5b919050565b5f60208284031215612213575f80fd5b611a92826121ed565b602081525f611a9260208301846119ea565b602081525f611a926020830184611e91565b606081525f6122526060830186611c49565b82810360208401526122648186611cc0565b90508281036040840152611e878185611d3a565b6001600160a01b0383168152604060208201525f611a6f60408301846119bf565b8215158152604060208201525f611a6f60408301846119bf565b602081525f611a926020830184612111565b606081016122f98284805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b92915050565b602081525f611a926020830184611db8565b805180151581146121fe575f80fd5b5f8060408385031215612331575f80fd5b61233a836121ed565b915061234860208401612311565b90509250929050565b80516121fe816118c6565b5f82601f83011261236b575f80fd5b81516123796120c182612045565b81815284602083860101111561238d575f80fd5b611a6f82602083016020870161199d565b5f60a082840312156123ae575f80fd5b6123b6611f81565b90506123c182612311565b815260208201516123d1816118c6565b6020820152604082015167ffffffffffffffff808211156123f0575f80fd5b6123fc8583860161235c565b60408401526060840151915080821115612414575f80fd5b506124218482850161235c565b6060830152506080820151612435816118c6565b608082015292915050565b5f8060408385031215612451575f80fd5b61245a836121ed565b9150602083015167ffffffffffffffff811115612475575f80fd5b6124818582860161239e565b9150509250929050565b5f806040838503121561249c575f80fd5b6124a5836121ed565b91506020830151611ad3816118c6565b80516121fe81611a99565b5f67ffffffffffffffff8211156124d9576124d9611f6d565b5060051b60200190565b5f82601f8301126124f2575f80fd5b815160206125026120c1836124c0565b82815260059290921b84018101918181019086841115612520575f80fd5b8286015b8481101561259c57805167ffffffffffffffff80821115612543575f80fd5b908801906040828b03601f190181131561255b575f80fd5b612563611faa565b83880151815290830151908282111561257a575f80fd5b6125888c898487010161239e565b818901528652505050918301918301612524565b509695505050505050565b5f606082840312156125b7575f80fd5b6040516060810181811067ffffffffffffffff821117156125da576125da611f6d565b806040525080915082516125ed81611a99565b815260208301516125fd816118c6565b6020820152604083015161261081611a99565b6040919091015292915050565b5f610160828403121561262e575f80fd5b612636611fcd565b9050815167ffffffffffffffff8082111561264f575f80fd5b61265b8583860161235c565b83526020840151915080821115612670575f80fd5b61267c8583860161235c565b602084015261268d60408501612351565b604084015260608401519150808211156126a5575f80fd5b6126b18583860161235c565b60608401526126c260808501612311565b60808401526126d360a085016124b5565b60a08401526126e460c08501612311565b60c084015260e08401519150808211156126fc575f80fd5b50612709848285016124e3565b60e08301525061010061271e848285016125a7565b9082015292915050565b5f82601f830112612737575f80fd5b815160206127476120c1836124c0565b82815260a09283028501820192828201919087851115612765575f80fd5b8387015b85811015611b3b5781818a03121561277f575f80fd5b612787611f81565b815161279281611a99565b8152818601516127a1816118c6565b8187015260406127b2838201612311565b9082015260606127c3838201612311565b908201526080828101516127d6816118c6565b908201528452928401928101612769565b5f82601f8301126127f6575f80fd5b815160206128066120c1836124c0565b82815260c09283028501820192828201919087851115612824575f80fd5b8387015b85811015611b3b5781818a03121561283e575f80fd5b612846611ff1565b815161285181611a99565b81528186015161286081611a99565b8187015260408281015161287381611a99565b9082015260608281015161288681611a99565b908201526080612897838201612311565b9082015260a0828101516128aa816118c6565b908201528452928401928101612828565b5f82601f8301126128ca575f80fd5b815160206128da6120c1836124c0565b82815260c092830285018201928282019190878511156128f8575f80fd5b8387015b85811015611b3b5781818a031215612912575f80fd5b61291a611ff1565b815161292581611a99565b81528186015161293481611a99565b8187015260408281015161294781611a99565b9082015260608281015161295a816118c6565b90820152608061296b838201612311565b9082015260a08281015161297e816118c6565b9082015284529284019281016128fc565b5f61012082840312156129a0575f80fd5b6129a8611fcd565b9050815167ffffffffffffffff808211156129c1575f80fd5b6129cd8583860161261d565b83526129db602085016124b5565b60208401526129ec60408501612311565b60408401526129fd60608501612311565b6060840152612a0e60808501612311565b608084015260a0840151915080821115612a26575f80fd5b612a3285838601612728565b60a084015260c0840151915080821115612a4a575f80fd5b612a56858386016127e7565b60c084015260e0840151915080821115612a6e575f80fd5b612a7a858386016128bb565b60e084015261010091508184015181811115612a94575f80fd5b612aa08682870161235c565b8385015250505092915050565b5f8060408385031215612abe575f80fd5b612ac7836121ed565b9150602083015167ffffffffffffffff80821115612ae3575f80fd5b9084019060c08287031215612af6575f80fd5b612afe611ff1565b825182811115612b0c575f80fd5b612b188882860161298f565b825250612b27602084016124b5565b6020820152612b3860408401612351565b6040820152612b49606084016124b5565b6060820152608083015182811115612b5f575f80fd5b612b6b8882860161235c565b608083015250612b7d60a08401612351565b60a08201528093505050509250929050565b5f8060408385031215612ba0575f80fd5b612ba9836121ed565b9150602083015190509250929050565b5f805f8060808587031215612bcc575f80fd5b612bd5856121ed565b9350602085015167ffffffffffffffff80821115612bf1575f80fd5b612bfd88838901612728565b94506040870151915080821115612c12575f80fd5b612c1e888389016127e7565b93506060870151915080821115612c33575f80fd5b50612c40878288016128bb565b91505092959194509250565b5f8060408385031215612c5d575f80fd5b612c66836121ed565b9150612348602084016121ed565b5f8060408385031215612c85575f80fd5b612c8e836121ed565b9150602083015167ffffffffffffffff80821115612caa575f80fd5b9084019060408287031215612cbd575f80fd5b612cc5611faa565b825182811115612cd3575f80fd5b612cdf8882860161298f565b825250612cee602084016121ed565b60208201528093505050509250929050565b5f8060808385031215612d11575f80fd5b612d1a836121ed565b915061234884602085016125a7565b5f8060408385031215612d3a575f80fd5b612d43836121ed565b9150602083015167ffffffffffffffff811115612d5e575f80fd5b6124818582860161298f56fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa2646970667358221220a19bd3187e1fd9ceb9ea7b54d61dc38c6b754a8ad73115a59df097d2c151f14d64736f6c63430008180033", - "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063618dc65e1161009e5780638c99ef5d1161006e5780638c99ef5d146102d05780639b23d3d9146102fd578063a3ad5b5514610310578063c0b19b6d14610323578063f2f38a7414610344575f80fd5b8063618dc65e1461026857806369837dc2146102895780636a4dde21146102aa57806386f88d88146102bd575f80fd5b80633eed2c39116100e45780633eed2c39146101b95780634cbdb37b146101cc5780635a5e6c31146101ed5780635b9076b7146102155780635d2c5bad14610238575f80fd5b806313c05dd81461011557806315dacbea146101425780631955de0b1461016857806319db44b614610189575b5f80fd5b6101286101233660046118dd565b610365565b604080519283529015156020830152015b60405180910390f35b610155610150366004611925565b6103e0565b60405160079190910b8152602001610139565b61017b610176366004611973565b6104cf565b604051610139929190611a54565b61019c610197366004611973565b61057b565b604080519283526001600160a01b03909116602083015201610139565b6101286101c7366004611a77565b6105f1565b6101df6101da366004611aa7565b610668565b604051610139929190611f09565b6102006101fb3660046118dd565b6106db565b60408051928352602083019190915201610139565b610228610223366004611a77565b610749565b6040516101399493929190611f21565b61024b610246366004611a77565b6107d8565b6040805160079390930b835260039190910b602083015201610139565b61027b61027636600461206c565b610850565b6040516101399291906120f9565b61029c610297366004611a77565b610967565b60405161013992919061213c565b6101286102b8366004612154565b6109d9565b6101286102cb366004611a77565b610a4d565b6102e36102de366004611a77565b610abb565b6040805160079390930b8352901515602083015201610139565b61015561030b366004611925565b610b31565b6102e361031e366004612154565b610b75565b610336610331366004611a77565b610bec565b604051610139929190612180565b610357610352366004611a77565b610c70565b6040516101399291906121ba565b5f80610372858585610ce2565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146103a3575f80fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161045e91906121d2565b5f604051808303815f865af19150503d805f8114610497576040519150601f19603f3d011682016040523d82523d5f602084013e61049c565b606091505b5091509150816104ad5760156104c1565b808060200190518101906104c19190612203565b60030b979650505050505050565b6040805160a0810182525f80825260208201819052606092820183905282820192909252608081018290526105048484610dc2565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461053d575f80fd5b7faed084fbdf29b6ba2242463299d7270f64e0f8ced16013cfff249856bd8871578160405161056c919061221c565b60405180910390a19250929050565b5f806105878484610eeb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146105b8575f80fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb9060200161056c565b5f806105fc83610fac565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a16016821461062d575f80fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b5f6106716117bb565b61067b848461108a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146106ac575f80fd5b7f91ccf16c022fe2d397abee975516433182ab8f781d4ef14b66cc732526e66dcf8160405161056c919061222e565b5f806106e885858561115e565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610719575f80fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c8906020016103d0565b5f60608060606107588561122b565b604051600785900b8152939750919550935091505f80516020612d6b8339815191529060200160405180910390a1600784900b601614610796575f80fd5b7f2fc15414e589a7221dbee977ae9650a8990a7544fd1b3ae3ae62f4797f412a998383836040516107c993929190612240565b60405180910390a19193509193565b5f806107e38361130d565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461081c575f80fd5b604051600382900b81527f182137409609594f2b12128230091c673507ea4cab315d59415d5e3f8c301ad59060200161065b565b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161087c929190612278565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108ba91906121d2565b5f604051808303815f865af19150503d805f81146108f3576040519150601f19603f3d011682016040523d82523d5f602084013e6108f8565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161092e929190612299565b60405180910390a18161095157601560405180602001604052805f815250610955565b6016815b60039190910b97909650945050505050565b5f6109706117f5565b610979836113cb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146109aa575f80fd5b7f4ef7d8101cfcfd8272047933834c75def485d9965aef926f86f237d4e61ef6388160405161065b91906122b3565b5f806109e58484611495565b60405160079290920b808352935091505f80516020612d6b8339815191529060200160405180910390a160168214610a1b575f80fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e9060200161056c565b5f80610a588361156a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610a89575f80fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd9060200161065b565b5f80610ac683611599565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610aff575f80fd5b60405181151581527f5080c42cc33acbcea410fa6eaa925bd878674825501981184fdd53749f8478a89060200161065b565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610420565b5f80610b8184846115c8565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610bba575f80fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f9060200161056c565b604080516060810182525f80825260208201819052918101829052610c10836115ff565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610c41575f80fd5b7ffed17041c1dbab1a630961a1f2d469641f421ee8a8b0f717d6f840c75e4593338160405161065b91906122c5565b5f610c79611814565b610c82836116f1565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610cb3575f80fd5b7fd1a813e1ab0917de7318f3003f23664aed447e65204cf1e19c2c806e591c851f8160405161065b91906122ff565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663f49f40db60e01b17905290515f9182918291829161016791610d4b916121d2565b5f604051808303815f865af19150503d805f8114610d84576040519150601f19603f3d011682016040523d82523d5f602084013e610d89565b606091505b509150915081610d9b5760155f610daf565b80806020019051810190610daf9190612320565b60039190910b9890975095505050505050565b6040805160a0810182525f80825260208083018290526060838501819052808401526080830182905283516001600160a01b03871660248201526044808201879052855180830390910181526064909101855290810180516001600160e01b0316631e26e99760e11b179052925190928391829161016791610e4491906121d2565b5f604051808303815f865af19150503d805f8114610e7d576040519150601f19603f3d011682016040523d82523d5f602084013e610e82565b606091505b5091509150610eca6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b82610ed757601581610daf565b81806020019051810190610daf9190612440565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03166304c791b360e11b17905290515f9182918291829161016791610f48916121d2565b5f604051808303815f865af19150503d805f8114610f81576040519150601f19603f3d011682016040523d82523d5f602084013e610f86565b606091505b509150915081610f985760155f610955565b80806020019051810190610955919061248b565b6040516001600160a01b03821660248201525f908190819081906101679063a7daa18d60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161101591906121d2565b5f604051808303815f865af19150503d805f811461104e576040519150601f19603f3d011682016040523d82523d5f602084013e611053565b606091505b5091509150816110655760155f611079565b808060200190518101906110799190612320565b60039190910b969095509350505050565b5f6110936117bb565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b031663050fc3b560e31b17905290515f918291610167916110f2916121d2565b5f604051808303815f865af19150503d805f811461112b576040519150601f19603f3d011682016040523d82523d5f602084013e611130565b606091505b509150915061113d6117bb565b8261114a57601581610daf565b81806020019051810190610daf9190612aad565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663927da10560e01b17905290515f91829182918291610167916111c7916121d2565b5f604051808303815f865af19150503d805f8114611200576040519150601f19603f3d011682016040523d82523d5f602084013e611205565b606091505b5091509150816112175760155f610daf565b80806020019051810190610daf9190612b8f565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316630573b08d60e51b17905290515f91606091829182918591829161016791611289916121d2565b5f604051808303815f865af19150503d805f81146112c2576040519150601f19603f3d011682016040523d82523d5f602084013e6112c7565b606091505b50915091506060806060846112e05760158383836112f4565b838060200190518101906112f49190612bb9565b60039390930b9d919c509a509098509650505050505050565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03166393272baf60e01b17905290515f9182918291829161016791611366916121d2565b5f604051808303815f865af19150503d805f811461139f576040519150601f19603f3d011682016040523d82523d5f602084013e6113a4565b606091505b5091509150816113b75760155f19611079565b808060200190518101906110799190612c4c565b5f6113d46117f5565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316633f28a19b60e01b17905290515f91829161016791611429916121d2565b5f604051808303815f865af19150503d805f8114611462576040519150601f19603f3d011682016040523d82523d5f602084013e611467565b606091505b50915091506114746117f5565b8261148157601581610955565b818060200190518101906109559190612c74565b6040516001600160a01b038381166024830152821660448201525f90819081908190610167906346de0fb160e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161150691906121d2565b5f604051808303815f865af19150503d805f811461153f576040519150601f19603f3d011682016040523d82523d5f602084013e611544565b606091505b5091509150816115565760155f610955565b808060200190518101906109559190612320565b6040516001600160a01b03821660248201525f908190819081906101679063335e04c160e01b90604401610fd7565b6040516001600160a01b03821660248201525f90819081908190610167906319f3736160e01b90604401610fd7565b6040516001600160a01b038381166024830152821660448201525f9081908190819061016790633cb0c7fd60e21b906064016114c8565b604080516060810182525f808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b17905292519092839182916101679161167091906121d2565b5f604051808303815f865af19150503d805f81146116a9576040519150601f19603f3d011682016040523d82523d5f602084013e6116ae565b606091505b50604080516060810182525f80825260208201819052918101919091529193509150826116dd57601581610955565b818060200190518101906109559190612d00565b5f6116fa611814565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316631f69565f60e01b17905290515f9182916101679161174f916121d2565b5f604051808303815f865af19150503d805f8114611788576040519150601f19603f3d011682016040523d82523d5f602084013e61178d565b606091505b509150915061179a611814565b826117a757601581610955565b818060200190518101906109559190612d29565b6040518060c001604052806117ce611814565b81525f60208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280611808611814565b81525f60209091015290565b60408051610240810182526060610120820181815261014083018290525f610160840181905261018084018390526101a084018190526101c084018190526101e08401819052610200840183905284519283018552808352602083018190529382019390935261022082015290819081526020015f60070b81526020015f151581526020015f151581526020015f15158152602001606081526020016060815260200160608152602001606081525090565b6001600160a01b03811681146118da575f80fd5b50565b5f805f606084860312156118ef575f80fd5b83356118fa816118c6565b9250602084013561190a816118c6565b9150604084013561191a816118c6565b809150509250925092565b5f805f8060808587031215611938575f80fd5b8435611943816118c6565b93506020850135611953816118c6565b92506040850135611963816118c6565b9396929550929360600135925050565b5f8060408385031215611984575f80fd5b823561198f816118c6565b946020939093013593505050565b5f5b838110156119b757818101518382015260200161199f565b50505f910152565b5f81518084526119d681602086016020860161199d565b601f01601f19169290920160200192915050565b8051151582525f60208201516001600160a01b0380821660208601526040840151915060a06040860152611a2160a08601836119bf565b915060608401518583036060870152611a3a83826119bf565b925050806080850151166080860152508091505092915050565b8260070b8152604060208201525f611a6f60408301846119ea565b949350505050565b5f60208284031215611a87575f80fd5b8135611a92816118c6565b9392505050565b8060070b81146118da575f80fd5b5f8060408385031215611ab8575f80fd5b8235611ac3816118c6565b91506020830135611ad381611a99565b809150509250929050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611b3b57858303601f190189528151805184528401516040858501819052611b27818601836119ea565b9a86019a9450505090830190600101611af9565b5090979650505050505050565b5f6101608251818552611b5d828601826119bf565b91505060208301518482036020860152611b7782826119bf565b9150506040830151611b9460408601826001600160a01b03169052565b5060608301518482036060860152611bac82826119bf565b9150506080830151611bc2608086018215159052565b5060a0830151611bd760a086018260070b9052565b5060c0830151611beb60c086018215159052565b5060e083015184820360e0860152611c038282611ade565b91505061010080840151611c3f82870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b83811015611cb5578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101611c5c565b509495945050505050565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a0152604080830151820b908a015260608083015190910b9089015260808082015115159089015260a0908101516001600160a01b03169088015260c09096019590820190600101611cd3565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a015260408083015190910b908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c09096019590820190600101611d4d565b5f6101208251818552611dcd82860182611b48565b9150506020830151611de4602086018260070b9052565b506040830151611df8604086018215159052565b506060830151611e0c606086018215159052565b506080830151611e20608086018215159052565b5060a083015184820360a0860152611e388282611c49565b91505060c083015184820360c0860152611e528282611cc0565b91505060e083015184820360e0860152611e6c8282611d3a565b9150506101008084015185830382870152611e8783826119bf565b9695505050505050565b5f815160c08452611ea560c0850182611db8565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b6060870152608085015191508583036080870152611eef83836119bf565b92508060a08601511660a087015250508091505092915050565b828152604060208201525f611a6f6040830184611e91565b8460070b8152608060208201525f611f3c6080830186611c49565b8281036040840152611f4e8186611cc0565b90508281036060840152611f628185611d3a565b979650505050505050565b634e487b7160e01b5f52604160045260245ffd5b60405160a0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405290565b6040805190810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051610120810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405160c0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051601f8201601f1916810167ffffffffffffffff8111828210171561203d5761203d611f6d565b604052919050565b5f67ffffffffffffffff82111561205e5761205e611f6d565b50601f01601f191660200190565b5f806040838503121561207d575f80fd5b8235612088816118c6565b9150602083013567ffffffffffffffff8111156120a3575f80fd5b8301601f810185136120b3575f80fd5b80356120c66120c182612045565b612014565b8181528660208385010111156120da575f80fd5b816020840160208301375f602083830101528093505050509250929050565b828152604060208201525f611a6f60408301846119bf565b5f8151604084526121256040850182611db8565b60209384015160030b949093019390935250919050565b828152604060208201525f611a6f6040830184612111565b5f8060408385031215612165575f80fd5b8235612170816118c6565b91506020830135611ad3816118c6565b82815260808101611a926020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b828152604060208201525f611a6f6040830184611db8565b5f82516121e381846020870161199d565b9190910192915050565b8051600381900b81146121fe575f80fd5b919050565b5f60208284031215612213575f80fd5b611a92826121ed565b602081525f611a9260208301846119ea565b602081525f611a926020830184611e91565b606081525f6122526060830186611c49565b82810360208401526122648186611cc0565b90508281036040840152611e878185611d3a565b6001600160a01b0383168152604060208201525f611a6f60408301846119bf565b8215158152604060208201525f611a6f60408301846119bf565b602081525f611a926020830184612111565b606081016122f98284805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b92915050565b602081525f611a926020830184611db8565b805180151581146121fe575f80fd5b5f8060408385031215612331575f80fd5b61233a836121ed565b915061234860208401612311565b90509250929050565b80516121fe816118c6565b5f82601f83011261236b575f80fd5b81516123796120c182612045565b81815284602083860101111561238d575f80fd5b611a6f82602083016020870161199d565b5f60a082840312156123ae575f80fd5b6123b6611f81565b90506123c182612311565b815260208201516123d1816118c6565b6020820152604082015167ffffffffffffffff808211156123f0575f80fd5b6123fc8583860161235c565b60408401526060840151915080821115612414575f80fd5b506124218482850161235c565b6060830152506080820151612435816118c6565b608082015292915050565b5f8060408385031215612451575f80fd5b61245a836121ed565b9150602083015167ffffffffffffffff811115612475575f80fd5b6124818582860161239e565b9150509250929050565b5f806040838503121561249c575f80fd5b6124a5836121ed565b91506020830151611ad3816118c6565b80516121fe81611a99565b5f67ffffffffffffffff8211156124d9576124d9611f6d565b5060051b60200190565b5f82601f8301126124f2575f80fd5b815160206125026120c1836124c0565b82815260059290921b84018101918181019086841115612520575f80fd5b8286015b8481101561259c57805167ffffffffffffffff80821115612543575f80fd5b908801906040828b03601f190181131561255b575f80fd5b612563611faa565b83880151815290830151908282111561257a575f80fd5b6125888c898487010161239e565b818901528652505050918301918301612524565b509695505050505050565b5f606082840312156125b7575f80fd5b6040516060810181811067ffffffffffffffff821117156125da576125da611f6d565b806040525080915082516125ed81611a99565b815260208301516125fd816118c6565b6020820152604083015161261081611a99565b6040919091015292915050565b5f610160828403121561262e575f80fd5b612636611fcd565b9050815167ffffffffffffffff8082111561264f575f80fd5b61265b8583860161235c565b83526020840151915080821115612670575f80fd5b61267c8583860161235c565b602084015261268d60408501612351565b604084015260608401519150808211156126a5575f80fd5b6126b18583860161235c565b60608401526126c260808501612311565b60808401526126d360a085016124b5565b60a08401526126e460c08501612311565b60c084015260e08401519150808211156126fc575f80fd5b50612709848285016124e3565b60e08301525061010061271e848285016125a7565b9082015292915050565b5f82601f830112612737575f80fd5b815160206127476120c1836124c0565b82815260a09283028501820192828201919087851115612765575f80fd5b8387015b85811015611b3b5781818a03121561277f575f80fd5b612787611f81565b815161279281611a99565b8152818601516127a1816118c6565b8187015260406127b2838201612311565b9082015260606127c3838201612311565b908201526080828101516127d6816118c6565b908201528452928401928101612769565b5f82601f8301126127f6575f80fd5b815160206128066120c1836124c0565b82815260c09283028501820192828201919087851115612824575f80fd5b8387015b85811015611b3b5781818a03121561283e575f80fd5b612846611ff1565b815161285181611a99565b81528186015161286081611a99565b8187015260408281015161287381611a99565b9082015260608281015161288681611a99565b908201526080612897838201612311565b9082015260a0828101516128aa816118c6565b908201528452928401928101612828565b5f82601f8301126128ca575f80fd5b815160206128da6120c1836124c0565b82815260c092830285018201928282019190878511156128f8575f80fd5b8387015b85811015611b3b5781818a031215612912575f80fd5b61291a611ff1565b815161292581611a99565b81528186015161293481611a99565b8187015260408281015161294781611a99565b9082015260608281015161295a816118c6565b90820152608061296b838201612311565b9082015260a08281015161297e816118c6565b9082015284529284019281016128fc565b5f61012082840312156129a0575f80fd5b6129a8611fcd565b9050815167ffffffffffffffff808211156129c1575f80fd5b6129cd8583860161261d565b83526129db602085016124b5565b60208401526129ec60408501612311565b60408401526129fd60608501612311565b6060840152612a0e60808501612311565b608084015260a0840151915080821115612a26575f80fd5b612a3285838601612728565b60a084015260c0840151915080821115612a4a575f80fd5b612a56858386016127e7565b60c084015260e0840151915080821115612a6e575f80fd5b612a7a858386016128bb565b60e084015261010091508184015181811115612a94575f80fd5b612aa08682870161235c565b8385015250505092915050565b5f8060408385031215612abe575f80fd5b612ac7836121ed565b9150602083015167ffffffffffffffff80821115612ae3575f80fd5b9084019060c08287031215612af6575f80fd5b612afe611ff1565b825182811115612b0c575f80fd5b612b188882860161298f565b825250612b27602084016124b5565b6020820152612b3860408401612351565b6040820152612b49606084016124b5565b6060820152608083015182811115612b5f575f80fd5b612b6b8882860161235c565b608083015250612b7d60a08401612351565b60a08201528093505050509250929050565b5f8060408385031215612ba0575f80fd5b612ba9836121ed565b9150602083015190509250929050565b5f805f8060808587031215612bcc575f80fd5b612bd5856121ed565b9350602085015167ffffffffffffffff80821115612bf1575f80fd5b612bfd88838901612728565b94506040870151915080821115612c12575f80fd5b612c1e888389016127e7565b93506060870151915080821115612c33575f80fd5b50612c40878288016128bb565b91505092959194509250565b5f8060408385031215612c5d575f80fd5b612c66836121ed565b9150612348602084016121ed565b5f8060408385031215612c85575f80fd5b612c8e836121ed565b9150602083015167ffffffffffffffff80821115612caa575f80fd5b9084019060408287031215612cbd575f80fd5b612cc5611faa565b825182811115612cd3575f80fd5b612cdf8882860161298f565b825250612cee602084016121ed565b60208201528093505050509250929050565b5f8060808385031215612d11575f80fd5b612d1a836121ed565b915061234884602085016125a7565b5f8060408385031215612d3a575f80fd5b612d43836121ed565b9150602083015167ffffffffffffffff811115612d5e575f80fd5b6124818582860161298f56fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa2646970667358221220a19bd3187e1fd9ceb9ea7b54d61dc38c6b754a8ad73115a59df097d2c151f14d64736f6c63430008180033", + "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a55612dc0806101235f395ff3fe608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063618dc65e1161009e5780638c99ef5d1161006e5780638c99ef5d146102d05780639b23d3d9146102fd578063a3ad5b5514610310578063c0b19b6d14610323578063f2f38a7414610344575f80fd5b8063618dc65e1461026857806369837dc2146102895780636a4dde21146102aa57806386f88d88146102bd575f80fd5b80633eed2c39116100e45780633eed2c39146101b95780634cbdb37b146101cc5780635a5e6c31146101ed5780635b9076b7146102155780635d2c5bad14610238575f80fd5b806313c05dd81461011557806315dacbea146101425780631955de0b1461016857806319db44b614610189575b5f80fd5b6101286101233660046118dd565b610365565b604080519283529015156020830152015b60405180910390f35b610155610150366004611925565b6103e0565b60405160079190910b8152602001610139565b61017b610176366004611973565b6104cf565b604051610139929190611a54565b61019c610197366004611973565b61057b565b604080519283526001600160a01b03909116602083015201610139565b6101286101c7366004611a77565b6105f1565b6101df6101da366004611aa7565b610668565b604051610139929190611f09565b6102006101fb3660046118dd565b6106db565b60408051928352602083019190915201610139565b610228610223366004611a77565b610749565b6040516101399493929190611f21565b61024b610246366004611a77565b6107d8565b6040805160079390930b835260039190910b602083015201610139565b61027b61027636600461206c565b610850565b6040516101399291906120f9565b61029c610297366004611a77565b610967565b60405161013992919061213c565b6101286102b8366004612154565b6109d9565b6101286102cb366004611a77565b610a4d565b6102e36102de366004611a77565b610abb565b6040805160079390930b8352901515602083015201610139565b61015561030b366004611925565b610b31565b6102e361031e366004612154565b610b75565b610336610331366004611a77565b610bec565b604051610139929190612180565b610357610352366004611a77565b610c70565b6040516101399291906121ba565b5f80610372858585610ce2565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146103a3575f80fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161045e91906121d2565b5f604051808303815f865af19150503d805f8114610497576040519150601f19603f3d011682016040523d82523d5f602084013e61049c565b606091505b5091509150816104ad5760156104c1565b808060200190518101906104c19190612203565b60030b979650505050505050565b6040805160a0810182525f80825260208201819052606092820183905282820192909252608081018290526105048484610dc2565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461053d575f80fd5b7faed084fbdf29b6ba2242463299d7270f64e0f8ced16013cfff249856bd8871578160405161056c919061221c565b60405180910390a19250929050565b5f806105878484610eeb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146105b8575f80fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb9060200161056c565b5f806105fc83610fac565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a16016821461062d575f80fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b5f6106716117bb565b61067b848461108a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146106ac575f80fd5b7f91ccf16c022fe2d397abee975516433182ab8f781d4ef14b66cc732526e66dcf8160405161056c919061222e565b5f806106e885858561115e565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610719575f80fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c8906020016103d0565b5f60608060606107588561122b565b604051600785900b8152939750919550935091505f80516020612d6b8339815191529060200160405180910390a1600784900b601614610796575f80fd5b7f2fc15414e589a7221dbee977ae9650a8990a7544fd1b3ae3ae62f4797f412a998383836040516107c993929190612240565b60405180910390a19193509193565b5f806107e38361130d565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461081c575f80fd5b604051600382900b81527f182137409609594f2b12128230091c673507ea4cab315d59415d5e3f8c301ad59060200161065b565b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161087c929190612278565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108ba91906121d2565b5f604051808303815f865af19150503d805f81146108f3576040519150601f19603f3d011682016040523d82523d5f602084013e6108f8565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161092e929190612299565b60405180910390a18161095157601560405180602001604052805f815250610955565b6016815b60039190910b97909650945050505050565b5f6109706117f5565b610979836113cb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146109aa575f80fd5b7f4ef7d8101cfcfd8272047933834c75def485d9965aef926f86f237d4e61ef6388160405161065b91906122b3565b5f806109e58484611495565b60405160079290920b808352935091505f80516020612d6b8339815191529060200160405180910390a160168214610a1b575f80fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e9060200161056c565b5f80610a588361156a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610a89575f80fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd9060200161065b565b5f80610ac683611599565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610aff575f80fd5b60405181151581527f5080c42cc33acbcea410fa6eaa925bd878674825501981184fdd53749f8478a89060200161065b565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610420565b5f80610b8184846115c8565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610bba575f80fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f9060200161056c565b604080516060810182525f80825260208201819052918101829052610c10836115ff565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610c41575f80fd5b7ffed17041c1dbab1a630961a1f2d469641f421ee8a8b0f717d6f840c75e4593338160405161065b91906122c5565b5f610c79611814565b610c82836116f1565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610cb3575f80fd5b7fd1a813e1ab0917de7318f3003f23664aed447e65204cf1e19c2c806e591c851f8160405161065b91906122ff565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663f49f40db60e01b17905290515f9182918291829161016791610d4b916121d2565b5f604051808303815f865af19150503d805f8114610d84576040519150601f19603f3d011682016040523d82523d5f602084013e610d89565b606091505b509150915081610d9b5760155f610daf565b80806020019051810190610daf9190612320565b60039190910b9890975095505050505050565b6040805160a0810182525f80825260208083018290526060838501819052808401526080830182905283516001600160a01b03871660248201526044808201879052855180830390910181526064909101855290810180516001600160e01b0316631e26e99760e11b179052925190928391829161016791610e4491906121d2565b5f604051808303815f865af19150503d805f8114610e7d576040519150601f19603f3d011682016040523d82523d5f602084013e610e82565b606091505b5091509150610eca6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b82610ed757601581610daf565b81806020019051810190610daf9190612440565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03166304c791b360e11b17905290515f9182918291829161016791610f48916121d2565b5f604051808303815f865af19150503d805f8114610f81576040519150601f19603f3d011682016040523d82523d5f602084013e610f86565b606091505b509150915081610f985760155f610955565b80806020019051810190610955919061248b565b6040516001600160a01b03821660248201525f908190819081906101679063a7daa18d60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161101591906121d2565b5f604051808303815f865af19150503d805f811461104e576040519150601f19603f3d011682016040523d82523d5f602084013e611053565b606091505b5091509150816110655760155f611079565b808060200190518101906110799190612320565b60039190910b969095509350505050565b5f6110936117bb565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b031663050fc3b560e31b17905290515f918291610167916110f2916121d2565b5f604051808303815f865af19150503d805f811461112b576040519150601f19603f3d011682016040523d82523d5f602084013e611130565b606091505b509150915061113d6117bb565b8261114a57601581610daf565b81806020019051810190610daf9190612aad565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663927da10560e01b17905290515f91829182918291610167916111c7916121d2565b5f604051808303815f865af19150503d805f8114611200576040519150601f19603f3d011682016040523d82523d5f602084013e611205565b606091505b5091509150816112175760155f610daf565b80806020019051810190610daf9190612b8f565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316630573b08d60e51b17905290515f91606091829182918591829161016791611289916121d2565b5f604051808303815f865af19150503d805f81146112c2576040519150601f19603f3d011682016040523d82523d5f602084013e6112c7565b606091505b50915091506060806060846112e05760158383836112f4565b838060200190518101906112f49190612bb9565b60039390930b9d919c509a509098509650505050505050565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03166393272baf60e01b17905290515f9182918291829161016791611366916121d2565b5f604051808303815f865af19150503d805f811461139f576040519150601f19603f3d011682016040523d82523d5f602084013e6113a4565b606091505b5091509150816113b75760155f19611079565b808060200190518101906110799190612c4c565b5f6113d46117f5565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316633f28a19b60e01b17905290515f91829161016791611429916121d2565b5f604051808303815f865af19150503d805f8114611462576040519150601f19603f3d011682016040523d82523d5f602084013e611467565b606091505b50915091506114746117f5565b8261148157601581610955565b818060200190518101906109559190612c74565b6040516001600160a01b038381166024830152821660448201525f90819081908190610167906346de0fb160e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161150691906121d2565b5f604051808303815f865af19150503d805f811461153f576040519150601f19603f3d011682016040523d82523d5f602084013e611544565b606091505b5091509150816115565760155f610955565b808060200190518101906109559190612320565b6040516001600160a01b03821660248201525f908190819081906101679063335e04c160e01b90604401610fd7565b6040516001600160a01b03821660248201525f90819081908190610167906319f3736160e01b90604401610fd7565b6040516001600160a01b038381166024830152821660448201525f9081908190819061016790633cb0c7fd60e21b906064016114c8565b604080516060810182525f808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b17905292519092839182916101679161167091906121d2565b5f604051808303815f865af19150503d805f81146116a9576040519150601f19603f3d011682016040523d82523d5f602084013e6116ae565b606091505b50604080516060810182525f80825260208201819052918101919091529193509150826116dd57601581610955565b818060200190518101906109559190612d00565b5f6116fa611814565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316631f69565f60e01b17905290515f9182916101679161174f916121d2565b5f604051808303815f865af19150503d805f8114611788576040519150601f19603f3d011682016040523d82523d5f602084013e61178d565b606091505b509150915061179a611814565b826117a757601581610955565b818060200190518101906109559190612d29565b6040518060c001604052806117ce611814565b81525f60208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280611808611814565b81525f60209091015290565b60408051610240810182526060610120820181815261014083018290525f610160840181905261018084018390526101a084018190526101c084018190526101e08401819052610200840183905284519283018552808352602083018190529382019390935261022082015290819081526020015f60070b81526020015f151581526020015f151581526020015f15158152602001606081526020016060815260200160608152602001606081525090565b6001600160a01b03811681146118da575f80fd5b50565b5f805f606084860312156118ef575f80fd5b83356118fa816118c6565b9250602084013561190a816118c6565b9150604084013561191a816118c6565b809150509250925092565b5f805f8060808587031215611938575f80fd5b8435611943816118c6565b93506020850135611953816118c6565b92506040850135611963816118c6565b9396929550929360600135925050565b5f8060408385031215611984575f80fd5b823561198f816118c6565b946020939093013593505050565b5f5b838110156119b757818101518382015260200161199f565b50505f910152565b5f81518084526119d681602086016020860161199d565b601f01601f19169290920160200192915050565b8051151582525f60208201516001600160a01b0380821660208601526040840151915060a06040860152611a2160a08601836119bf565b915060608401518583036060870152611a3a83826119bf565b925050806080850151166080860152508091505092915050565b8260070b8152604060208201525f611a6f60408301846119ea565b949350505050565b5f60208284031215611a87575f80fd5b8135611a92816118c6565b9392505050565b8060070b81146118da575f80fd5b5f8060408385031215611ab8575f80fd5b8235611ac3816118c6565b91506020830135611ad381611a99565b809150509250929050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611b3b57858303601f190189528151805184528401516040858501819052611b27818601836119ea565b9a86019a9450505090830190600101611af9565b5090979650505050505050565b5f6101608251818552611b5d828601826119bf565b91505060208301518482036020860152611b7782826119bf565b9150506040830151611b9460408601826001600160a01b03169052565b5060608301518482036060860152611bac82826119bf565b9150506080830151611bc2608086018215159052565b5060a0830151611bd760a086018260070b9052565b5060c0830151611beb60c086018215159052565b5060e083015184820360e0860152611c038282611ade565b91505061010080840151611c3f82870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b83811015611cb5578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101611c5c565b509495945050505050565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a0152604080830151820b908a015260608083015190910b9089015260808082015115159089015260a0908101516001600160a01b03169088015260c09096019590820190600101611cd3565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a015260408083015190910b908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c09096019590820190600101611d4d565b5f6101208251818552611dcd82860182611b48565b9150506020830151611de4602086018260070b9052565b506040830151611df8604086018215159052565b506060830151611e0c606086018215159052565b506080830151611e20608086018215159052565b5060a083015184820360a0860152611e388282611c49565b91505060c083015184820360c0860152611e528282611cc0565b91505060e083015184820360e0860152611e6c8282611d3a565b9150506101008084015185830382870152611e8783826119bf565b9695505050505050565b5f815160c08452611ea560c0850182611db8565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b6060870152608085015191508583036080870152611eef83836119bf565b92508060a08601511660a087015250508091505092915050565b828152604060208201525f611a6f6040830184611e91565b8460070b8152608060208201525f611f3c6080830186611c49565b8281036040840152611f4e8186611cc0565b90508281036060840152611f628185611d3a565b979650505050505050565b634e487b7160e01b5f52604160045260245ffd5b60405160a0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405290565b6040805190810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051610120810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405160c0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051601f8201601f1916810167ffffffffffffffff8111828210171561203d5761203d611f6d565b604052919050565b5f67ffffffffffffffff82111561205e5761205e611f6d565b50601f01601f191660200190565b5f806040838503121561207d575f80fd5b8235612088816118c6565b9150602083013567ffffffffffffffff8111156120a3575f80fd5b8301601f810185136120b3575f80fd5b80356120c66120c182612045565b612014565b8181528660208385010111156120da575f80fd5b816020840160208301375f602083830101528093505050509250929050565b828152604060208201525f611a6f60408301846119bf565b5f8151604084526121256040850182611db8565b60209384015160030b949093019390935250919050565b828152604060208201525f611a6f6040830184612111565b5f8060408385031215612165575f80fd5b8235612170816118c6565b91506020830135611ad3816118c6565b82815260808101611a926020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b828152604060208201525f611a6f6040830184611db8565b5f82516121e381846020870161199d565b9190910192915050565b8051600381900b81146121fe575f80fd5b919050565b5f60208284031215612213575f80fd5b611a92826121ed565b602081525f611a9260208301846119ea565b602081525f611a926020830184611e91565b606081525f6122526060830186611c49565b82810360208401526122648186611cc0565b90508281036040840152611e878185611d3a565b6001600160a01b0383168152604060208201525f611a6f60408301846119bf565b8215158152604060208201525f611a6f60408301846119bf565b602081525f611a926020830184612111565b606081016122f98284805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b92915050565b602081525f611a926020830184611db8565b805180151581146121fe575f80fd5b5f8060408385031215612331575f80fd5b61233a836121ed565b915061234860208401612311565b90509250929050565b80516121fe816118c6565b5f82601f83011261236b575f80fd5b81516123796120c182612045565b81815284602083860101111561238d575f80fd5b611a6f82602083016020870161199d565b5f60a082840312156123ae575f80fd5b6123b6611f81565b90506123c182612311565b815260208201516123d1816118c6565b6020820152604082015167ffffffffffffffff808211156123f0575f80fd5b6123fc8583860161235c565b60408401526060840151915080821115612414575f80fd5b506124218482850161235c565b6060830152506080820151612435816118c6565b608082015292915050565b5f8060408385031215612451575f80fd5b61245a836121ed565b9150602083015167ffffffffffffffff811115612475575f80fd5b6124818582860161239e565b9150509250929050565b5f806040838503121561249c575f80fd5b6124a5836121ed565b91506020830151611ad3816118c6565b80516121fe81611a99565b5f67ffffffffffffffff8211156124d9576124d9611f6d565b5060051b60200190565b5f82601f8301126124f2575f80fd5b815160206125026120c1836124c0565b82815260059290921b84018101918181019086841115612520575f80fd5b8286015b8481101561259c57805167ffffffffffffffff80821115612543575f80fd5b908801906040828b03601f190181131561255b575f80fd5b612563611faa565b83880151815290830151908282111561257a575f80fd5b6125888c898487010161239e565b818901528652505050918301918301612524565b509695505050505050565b5f606082840312156125b7575f80fd5b6040516060810181811067ffffffffffffffff821117156125da576125da611f6d565b806040525080915082516125ed81611a99565b815260208301516125fd816118c6565b6020820152604083015161261081611a99565b6040919091015292915050565b5f610160828403121561262e575f80fd5b612636611fcd565b9050815167ffffffffffffffff8082111561264f575f80fd5b61265b8583860161235c565b83526020840151915080821115612670575f80fd5b61267c8583860161235c565b602084015261268d60408501612351565b604084015260608401519150808211156126a5575f80fd5b6126b18583860161235c565b60608401526126c260808501612311565b60808401526126d360a085016124b5565b60a08401526126e460c08501612311565b60c084015260e08401519150808211156126fc575f80fd5b50612709848285016124e3565b60e08301525061010061271e848285016125a7565b9082015292915050565b5f82601f830112612737575f80fd5b815160206127476120c1836124c0565b82815260a09283028501820192828201919087851115612765575f80fd5b8387015b85811015611b3b5781818a03121561277f575f80fd5b612787611f81565b815161279281611a99565b8152818601516127a1816118c6565b8187015260406127b2838201612311565b9082015260606127c3838201612311565b908201526080828101516127d6816118c6565b908201528452928401928101612769565b5f82601f8301126127f6575f80fd5b815160206128066120c1836124c0565b82815260c09283028501820192828201919087851115612824575f80fd5b8387015b85811015611b3b5781818a03121561283e575f80fd5b612846611ff1565b815161285181611a99565b81528186015161286081611a99565b8187015260408281015161287381611a99565b9082015260608281015161288681611a99565b908201526080612897838201612311565b9082015260a0828101516128aa816118c6565b908201528452928401928101612828565b5f82601f8301126128ca575f80fd5b815160206128da6120c1836124c0565b82815260c092830285018201928282019190878511156128f8575f80fd5b8387015b85811015611b3b5781818a031215612912575f80fd5b61291a611ff1565b815161292581611a99565b81528186015161293481611a99565b8187015260408281015161294781611a99565b9082015260608281015161295a816118c6565b90820152608061296b838201612311565b9082015260a08281015161297e816118c6565b9082015284529284019281016128fc565b5f61012082840312156129a0575f80fd5b6129a8611fcd565b9050815167ffffffffffffffff808211156129c1575f80fd5b6129cd8583860161261d565b83526129db602085016124b5565b60208401526129ec60408501612311565b60408401526129fd60608501612311565b6060840152612a0e60808501612311565b608084015260a0840151915080821115612a26575f80fd5b612a3285838601612728565b60a084015260c0840151915080821115612a4a575f80fd5b612a56858386016127e7565b60c084015260e0840151915080821115612a6e575f80fd5b612a7a858386016128bb565b60e084015261010091508184015181811115612a94575f80fd5b612aa08682870161235c565b8385015250505092915050565b5f8060408385031215612abe575f80fd5b612ac7836121ed565b9150602083015167ffffffffffffffff80821115612ae3575f80fd5b9084019060c08287031215612af6575f80fd5b612afe611ff1565b825182811115612b0c575f80fd5b612b188882860161298f565b825250612b27602084016124b5565b6020820152612b3860408401612351565b6040820152612b49606084016124b5565b6060820152608083015182811115612b5f575f80fd5b612b6b8882860161235c565b608083015250612b7d60a08401612351565b60a08201528093505050509250929050565b5f8060408385031215612ba0575f80fd5b612ba9836121ed565b9150602083015190509250929050565b5f805f8060808587031215612bcc575f80fd5b612bd5856121ed565b9350602085015167ffffffffffffffff80821115612bf1575f80fd5b612bfd88838901612728565b94506040870151915080821115612c12575f80fd5b612c1e888389016127e7565b93506060870151915080821115612c33575f80fd5b50612c40878288016128bb565b91505092959194509250565b5f8060408385031215612c5d575f80fd5b612c66836121ed565b9150612348602084016121ed565b5f8060408385031215612c85575f80fd5b612c8e836121ed565b9150602083015167ffffffffffffffff80821115612caa575f80fd5b9084019060408287031215612cbd575f80fd5b612cc5611faa565b825182811115612cd3575f80fd5b612cdf8882860161298f565b825250612cee602084016121ed565b60208201528093505050509250929050565b5f8060808385031215612d11575f80fd5b612d1a836121ed565b915061234884602085016125a7565b5f8060408385031215612d3a575f80fd5b612d43836121ed565b9150602083015167ffffffffffffffff811115612d5e575f80fd5b6124818582860161298f56fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa2646970667358221220b6799bbd2808a8d828ef80aab7feb21d287919944d72a3f8ca0c57ade7ebea0b64736f6c63430008180033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063618dc65e1161009e5780638c99ef5d1161006e5780638c99ef5d146102d05780639b23d3d9146102fd578063a3ad5b5514610310578063c0b19b6d14610323578063f2f38a7414610344575f80fd5b8063618dc65e1461026857806369837dc2146102895780636a4dde21146102aa57806386f88d88146102bd575f80fd5b80633eed2c39116100e45780633eed2c39146101b95780634cbdb37b146101cc5780635a5e6c31146101ed5780635b9076b7146102155780635d2c5bad14610238575f80fd5b806313c05dd81461011557806315dacbea146101425780631955de0b1461016857806319db44b614610189575b5f80fd5b6101286101233660046118dd565b610365565b604080519283529015156020830152015b60405180910390f35b610155610150366004611925565b6103e0565b60405160079190910b8152602001610139565b61017b610176366004611973565b6104cf565b604051610139929190611a54565b61019c610197366004611973565b61057b565b604080519283526001600160a01b03909116602083015201610139565b6101286101c7366004611a77565b6105f1565b6101df6101da366004611aa7565b610668565b604051610139929190611f09565b6102006101fb3660046118dd565b6106db565b60408051928352602083019190915201610139565b610228610223366004611a77565b610749565b6040516101399493929190611f21565b61024b610246366004611a77565b6107d8565b6040805160079390930b835260039190910b602083015201610139565b61027b61027636600461206c565b610850565b6040516101399291906120f9565b61029c610297366004611a77565b610967565b60405161013992919061213c565b6101286102b8366004612154565b6109d9565b6101286102cb366004611a77565b610a4d565b6102e36102de366004611a77565b610abb565b6040805160079390930b8352901515602083015201610139565b61015561030b366004611925565b610b31565b6102e361031e366004612154565b610b75565b610336610331366004611a77565b610bec565b604051610139929190612180565b610357610352366004611a77565b610c70565b6040516101399291906121ba565b5f80610372858585610ce2565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146103a3575f80fd5b60405181151581527e1c2e72360171244b3bb8cc8ddd767820edf37138ad6f129fb3574b407c307d906020015b60405180910390a1935093915050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161045e91906121d2565b5f604051808303815f865af19150503d805f8114610497576040519150601f19603f3d011682016040523d82523d5f602084013e61049c565b606091505b5091509150816104ad5760156104c1565b808060200190518101906104c19190612203565b60030b979650505050505050565b6040805160a0810182525f80825260208201819052606092820183905282820192909252608081018290526105048484610dc2565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461053d575f80fd5b7faed084fbdf29b6ba2242463299d7270f64e0f8ced16013cfff249856bd8871578160405161056c919061221c565b60405180910390a19250929050565b5f806105878484610eeb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146105b8575f80fd5b6040516001600160a01b03821681527fc2c78c7c31baf14949e75c51df12be56edb9af523cf82839c2869bbcf13b3ecb9060200161056c565b5f806105fc83610fac565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a16016821461062d575f80fd5b60405181151581527f6b7f3306751292f85ab4161ee2b0ac16dfc8ded13e6446ce6bd859d0a2f4c78e906020015b60405180910390a1915091565b5f6106716117bb565b61067b848461108a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146106ac575f80fd5b7f91ccf16c022fe2d397abee975516433182ab8f781d4ef14b66cc732526e66dcf8160405161056c919061222e565b5f806106e885858561115e565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610719575f80fd5b6040518181527f25b6684a7e8fe1b676e9c39c8dd65034fbafea906d3bdfd97bf748b7b55e14c8906020016103d0565b5f60608060606107588561122b565b604051600785900b8152939750919550935091505f80516020612d6b8339815191529060200160405180910390a1600784900b601614610796575f80fd5b7f2fc15414e589a7221dbee977ae9650a8990a7544fd1b3ae3ae62f4797f412a998383836040516107c993929190612240565b60405180910390a19193509193565b5f806107e38361130d565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b60161461081c575f80fd5b604051600382900b81527f182137409609594f2b12128230091c673507ea4cab315d59415d5e3f8c301ad59060200161065b565b5f60605f806101676001600160a01b031663618dc65e60e01b878760405160240161087c929190612278565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108ba91906121d2565b5f604051808303815f865af19150503d805f81146108f3576040519150601f19603f3d011682016040523d82523d5f602084013e6108f8565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161092e929190612299565b60405180910390a18161095157601560405180602001604052805f815250610955565b6016815b60039190910b97909650945050505050565b5f6109706117f5565b610979836113cb565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a1601682146109aa575f80fd5b7f4ef7d8101cfcfd8272047933834c75def485d9965aef926f86f237d4e61ef6388160405161065b91906122b3565b5f806109e58484611495565b60405160079290920b808352935091505f80516020612d6b8339815191529060200160405180910390a160168214610a1b575f80fd5b60405181151581527f59800d968fcce138300a0019410b4b75041610d65b3cdc5f31656b03ed14912e9060200161056c565b5f80610a588361156a565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610a89575f80fd5b60405181151581527f9ee19e13dfa1ba8db2502e15ff56dbecdeb0e0473323fb195473ce648030a2cd9060200161065b565b5f80610ac683611599565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610aff575f80fd5b60405181151581527f5080c42cc33acbcea410fa6eaa925bd878674825501981184fdd53749f8478a89060200161065b565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610420565b5f80610b8184846115c8565b604051600783900b815291935091505f80516020612d6b8339815191529060200160405180910390a1600782900b601614610bba575f80fd5b60405181151581527fd24dda6928587354b65aa1a18c2eaf249bef7e5bafd2a71fac71d286f76f957f9060200161056c565b604080516060810182525f80825260208201819052918101829052610c10836115ff565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610c41575f80fd5b7ffed17041c1dbab1a630961a1f2d469641f421ee8a8b0f717d6f840c75e4593338160405161065b91906122c5565b5f610c79611814565b610c82836116f1565b60405182815291935091505f80516020612d6b8339815191529060200160405180910390a160168214610cb3575f80fd5b7fd1a813e1ab0917de7318f3003f23664aed447e65204cf1e19c2c806e591c851f8160405161065b91906122ff565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663f49f40db60e01b17905290515f9182918291829161016791610d4b916121d2565b5f604051808303815f865af19150503d805f8114610d84576040519150601f19603f3d011682016040523d82523d5f602084013e610d89565b606091505b509150915081610d9b5760155f610daf565b80806020019051810190610daf9190612320565b60039190910b9890975095505050505050565b6040805160a0810182525f80825260208083018290526060838501819052808401526080830182905283516001600160a01b03871660248201526044808201879052855180830390910181526064909101855290810180516001600160e01b0316631e26e99760e11b179052925190928391829161016791610e4491906121d2565b5f604051808303815f865af19150503d805f8114610e7d576040519150601f19603f3d011682016040523d82523d5f602084013e610e82565b606091505b5091509150610eca6040518060a001604052805f151581526020015f6001600160a01b0316815260200160608152602001606081526020015f6001600160a01b031681525090565b82610ed757601581610daf565b81806020019051810190610daf9190612440565b604080516001600160a01b0384166024820152604480820184905282518083039091018152606490910182526020810180516001600160e01b03166304c791b360e11b17905290515f9182918291829161016791610f48916121d2565b5f604051808303815f865af19150503d805f8114610f81576040519150601f19603f3d011682016040523d82523d5f602084013e610f86565b606091505b509150915081610f985760155f610955565b80806020019051810190610955919061248b565b6040516001600160a01b03821660248201525f908190819081906101679063a7daa18d60e01b906044015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161101591906121d2565b5f604051808303815f865af19150503d805f811461104e576040519150601f19603f3d011682016040523d82523d5f602084013e611053565b606091505b5091509150816110655760155f611079565b808060200190518101906110799190612320565b60039190910b969095509350505050565b5f6110936117bb565b604080516001600160a01b0386166024820152600785900b60448083019190915282518083039091018152606490910182526020810180516001600160e01b031663050fc3b560e31b17905290515f918291610167916110f2916121d2565b5f604051808303815f865af19150503d805f811461112b576040519150601f19603f3d011682016040523d82523d5f602084013e611130565b606091505b509150915061113d6117bb565b8261114a57601581610daf565b81806020019051810190610daf9190612aad565b604080516001600160a01b0385811660248301528481166044830152831660648083019190915282518083039091018152608490910182526020810180516001600160e01b031663927da10560e01b17905290515f91829182918291610167916111c7916121d2565b5f604051808303815f865af19150503d805f8114611200576040519150601f19603f3d011682016040523d82523d5f602084013e611205565b606091505b5091509150816112175760155f610daf565b80806020019051810190610daf9190612b8f565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316630573b08d60e51b17905290515f91606091829182918591829161016791611289916121d2565b5f604051808303815f865af19150503d805f81146112c2576040519150601f19603f3d011682016040523d82523d5f602084013e6112c7565b606091505b50915091506060806060846112e05760158383836112f4565b838060200190518101906112f49190612bb9565b60039390930b9d919c509a509098509650505050505050565b604080516001600160a01b03831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03166393272baf60e01b17905290515f9182918291829161016791611366916121d2565b5f604051808303815f865af19150503d805f811461139f576040519150601f19603f3d011682016040523d82523d5f602084013e6113a4565b606091505b5091509150816113b75760155f19611079565b808060200190518101906110799190612c4c565b5f6113d46117f5565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316633f28a19b60e01b17905290515f91829161016791611429916121d2565b5f604051808303815f865af19150503d805f8114611462576040519150601f19603f3d011682016040523d82523d5f602084013e611467565b606091505b50915091506114746117f5565b8261148157601581610955565b818060200190518101906109559190612c74565b6040516001600160a01b038381166024830152821660448201525f90819081908190610167906346de0fb160e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161150691906121d2565b5f604051808303815f865af19150503d805f811461153f576040519150601f19603f3d011682016040523d82523d5f602084013e611544565b606091505b5091509150816115565760155f610955565b808060200190518101906109559190612320565b6040516001600160a01b03821660248201525f908190819081906101679063335e04c160e01b90604401610fd7565b6040516001600160a01b03821660248201525f90819081908190610167906319f3736160e01b90604401610fd7565b6040516001600160a01b038381166024830152821660448201525f9081908190819061016790633cb0c7fd60e21b906064016114c8565b604080516060810182525f808252602080830182905282840182905283516001600160a01b038616602480830191909152855180830390910181526044909101855290810180516001600160e01b0316631ac299b760e31b17905292519092839182916101679161167091906121d2565b5f604051808303815f865af19150503d805f81146116a9576040519150601f19603f3d011682016040523d82523d5f602084013e6116ae565b606091505b50604080516060810182525f80825260208201819052918101919091529193509150826116dd57601581610955565b818060200190518101906109559190612d00565b5f6116fa611814565b604080516001600160a01b03851660248083019190915282518083039091018152604490910182526020810180516001600160e01b0316631f69565f60e01b17905290515f9182916101679161174f916121d2565b5f604051808303815f865af19150503d805f8114611788576040519150601f19603f3d011682016040523d82523d5f602084013e61178d565b606091505b509150915061179a611814565b826117a757601581610955565b818060200190518101906109559190612d29565b6040518060c001604052806117ce611814565b81525f60208201819052604082018190526060808301829052608083015260a09091015290565b6040518060400160405280611808611814565b81525f60209091015290565b60408051610240810182526060610120820181815261014083018290525f610160840181905261018084018390526101a084018190526101c084018190526101e08401819052610200840183905284519283018552808352602083018190529382019390935261022082015290819081526020015f60070b81526020015f151581526020015f151581526020015f15158152602001606081526020016060815260200160608152602001606081525090565b6001600160a01b03811681146118da575f80fd5b50565b5f805f606084860312156118ef575f80fd5b83356118fa816118c6565b9250602084013561190a816118c6565b9150604084013561191a816118c6565b809150509250925092565b5f805f8060808587031215611938575f80fd5b8435611943816118c6565b93506020850135611953816118c6565b92506040850135611963816118c6565b9396929550929360600135925050565b5f8060408385031215611984575f80fd5b823561198f816118c6565b946020939093013593505050565b5f5b838110156119b757818101518382015260200161199f565b50505f910152565b5f81518084526119d681602086016020860161199d565b601f01601f19169290920160200192915050565b8051151582525f60208201516001600160a01b0380821660208601526040840151915060a06040860152611a2160a08601836119bf565b915060608401518583036060870152611a3a83826119bf565b925050806080850151166080860152508091505092915050565b8260070b8152604060208201525f611a6f60408301846119ea565b949350505050565b5f60208284031215611a87575f80fd5b8135611a92816118c6565b9392505050565b8060070b81146118da575f80fd5b5f8060408385031215611ab8575f80fd5b8235611ac3816118c6565b91506020830135611ad381611a99565b809150509250929050565b5f82825180855260208086019550808260051b8401018186015f5b84811015611b3b57858303601f190189528151805184528401516040858501819052611b27818601836119ea565b9a86019a9450505090830190600101611af9565b5090979650505050505050565b5f6101608251818552611b5d828601826119bf565b91505060208301518482036020860152611b7782826119bf565b9150506040830151611b9460408601826001600160a01b03169052565b5060608301518482036060860152611bac82826119bf565b9150506080830151611bc2608086018215159052565b5060a0830151611bd760a086018260070b9052565b5060c0830151611beb60c086018215159052565b5060e083015184820360e0860152611c038282611ade565b91505061010080840151611c3f82870182805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b5090949350505050565b5f815180845260208085019450602084015f5b83811015611cb5578151805160070b8852838101516001600160a01b03908116858a01526040808301511515908a01526060808301511515908a0152608091820151169088015260a09096019590820190600101611c5c565b509495945050505050565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a0152604080830151820b908a015260608083015190910b9089015260808082015115159089015260a0908101516001600160a01b03169088015260c09096019590820190600101611cd3565b5f815180845260208085019450602084015f5b83811015611cb55781518051600790810b895284820151810b858a015260408083015190910b908901526060808201516001600160a01b03908116918a01919091526080808301511515908a015260a091820151169088015260c09096019590820190600101611d4d565b5f6101208251818552611dcd82860182611b48565b9150506020830151611de4602086018260070b9052565b506040830151611df8604086018215159052565b506060830151611e0c606086018215159052565b506080830151611e20608086018215159052565b5060a083015184820360a0860152611e388282611c49565b91505060c083015184820360c0860152611e528282611cc0565b91505060e083015184820360e0860152611e6c8282611d3a565b9150506101008084015185830382870152611e8783826119bf565b9695505050505050565b5f815160c08452611ea560c0850182611db8565b9050602083015160070b602085015260408301516001600160a01b038082166040870152606085015160070b6060870152608085015191508583036080870152611eef83836119bf565b92508060a08601511660a087015250508091505092915050565b828152604060208201525f611a6f6040830184611e91565b8460070b8152608060208201525f611f3c6080830186611c49565b8281036040840152611f4e8186611cc0565b90508281036060840152611f628185611d3a565b979650505050505050565b634e487b7160e01b5f52604160045260245ffd5b60405160a0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405290565b6040805190810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051610120810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b60405160c0810167ffffffffffffffff81118282101715611fa457611fa4611f6d565b604051601f8201601f1916810167ffffffffffffffff8111828210171561203d5761203d611f6d565b604052919050565b5f67ffffffffffffffff82111561205e5761205e611f6d565b50601f01601f191660200190565b5f806040838503121561207d575f80fd5b8235612088816118c6565b9150602083013567ffffffffffffffff8111156120a3575f80fd5b8301601f810185136120b3575f80fd5b80356120c66120c182612045565b612014565b8181528660208385010111156120da575f80fd5b816020840160208301375f602083830101528093505050509250929050565b828152604060208201525f611a6f60408301846119bf565b5f8151604084526121256040850182611db8565b60209384015160030b949093019390935250919050565b828152604060208201525f611a6f6040830184612111565b5f8060408385031215612165575f80fd5b8235612170816118c6565b91506020830135611ad3816118c6565b82815260808101611a926020830184805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b828152604060208201525f611a6f6040830184611db8565b5f82516121e381846020870161199d565b9190910192915050565b8051600381900b81146121fe575f80fd5b919050565b5f60208284031215612213575f80fd5b611a92826121ed565b602081525f611a9260208301846119ea565b602081525f611a926020830184611e91565b606081525f6122526060830186611c49565b82810360208401526122648186611cc0565b90508281036040840152611e878185611d3a565b6001600160a01b0383168152604060208201525f611a6f60408301846119bf565b8215158152604060208201525f611a6f60408301846119bf565b602081525f611a926020830184612111565b606081016122f98284805160070b82526001600160a01b036020820151166020830152604081015160070b60408301525050565b92915050565b602081525f611a926020830184611db8565b805180151581146121fe575f80fd5b5f8060408385031215612331575f80fd5b61233a836121ed565b915061234860208401612311565b90509250929050565b80516121fe816118c6565b5f82601f83011261236b575f80fd5b81516123796120c182612045565b81815284602083860101111561238d575f80fd5b611a6f82602083016020870161199d565b5f60a082840312156123ae575f80fd5b6123b6611f81565b90506123c182612311565b815260208201516123d1816118c6565b6020820152604082015167ffffffffffffffff808211156123f0575f80fd5b6123fc8583860161235c565b60408401526060840151915080821115612414575f80fd5b506124218482850161235c565b6060830152506080820151612435816118c6565b608082015292915050565b5f8060408385031215612451575f80fd5b61245a836121ed565b9150602083015167ffffffffffffffff811115612475575f80fd5b6124818582860161239e565b9150509250929050565b5f806040838503121561249c575f80fd5b6124a5836121ed565b91506020830151611ad3816118c6565b80516121fe81611a99565b5f67ffffffffffffffff8211156124d9576124d9611f6d565b5060051b60200190565b5f82601f8301126124f2575f80fd5b815160206125026120c1836124c0565b82815260059290921b84018101918181019086841115612520575f80fd5b8286015b8481101561259c57805167ffffffffffffffff80821115612543575f80fd5b908801906040828b03601f190181131561255b575f80fd5b612563611faa565b83880151815290830151908282111561257a575f80fd5b6125888c898487010161239e565b818901528652505050918301918301612524565b509695505050505050565b5f606082840312156125b7575f80fd5b6040516060810181811067ffffffffffffffff821117156125da576125da611f6d565b806040525080915082516125ed81611a99565b815260208301516125fd816118c6565b6020820152604083015161261081611a99565b6040919091015292915050565b5f610160828403121561262e575f80fd5b612636611fcd565b9050815167ffffffffffffffff8082111561264f575f80fd5b61265b8583860161235c565b83526020840151915080821115612670575f80fd5b61267c8583860161235c565b602084015261268d60408501612351565b604084015260608401519150808211156126a5575f80fd5b6126b18583860161235c565b60608401526126c260808501612311565b60808401526126d360a085016124b5565b60a08401526126e460c08501612311565b60c084015260e08401519150808211156126fc575f80fd5b50612709848285016124e3565b60e08301525061010061271e848285016125a7565b9082015292915050565b5f82601f830112612737575f80fd5b815160206127476120c1836124c0565b82815260a09283028501820192828201919087851115612765575f80fd5b8387015b85811015611b3b5781818a03121561277f575f80fd5b612787611f81565b815161279281611a99565b8152818601516127a1816118c6565b8187015260406127b2838201612311565b9082015260606127c3838201612311565b908201526080828101516127d6816118c6565b908201528452928401928101612769565b5f82601f8301126127f6575f80fd5b815160206128066120c1836124c0565b82815260c09283028501820192828201919087851115612824575f80fd5b8387015b85811015611b3b5781818a03121561283e575f80fd5b612846611ff1565b815161285181611a99565b81528186015161286081611a99565b8187015260408281015161287381611a99565b9082015260608281015161288681611a99565b908201526080612897838201612311565b9082015260a0828101516128aa816118c6565b908201528452928401928101612828565b5f82601f8301126128ca575f80fd5b815160206128da6120c1836124c0565b82815260c092830285018201928282019190878511156128f8575f80fd5b8387015b85811015611b3b5781818a031215612912575f80fd5b61291a611ff1565b815161292581611a99565b81528186015161293481611a99565b8187015260408281015161294781611a99565b9082015260608281015161295a816118c6565b90820152608061296b838201612311565b9082015260a08281015161297e816118c6565b9082015284529284019281016128fc565b5f61012082840312156129a0575f80fd5b6129a8611fcd565b9050815167ffffffffffffffff808211156129c1575f80fd5b6129cd8583860161261d565b83526129db602085016124b5565b60208401526129ec60408501612311565b60408401526129fd60608501612311565b6060840152612a0e60808501612311565b608084015260a0840151915080821115612a26575f80fd5b612a3285838601612728565b60a084015260c0840151915080821115612a4a575f80fd5b612a56858386016127e7565b60c084015260e0840151915080821115612a6e575f80fd5b612a7a858386016128bb565b60e084015261010091508184015181811115612a94575f80fd5b612aa08682870161235c565b8385015250505092915050565b5f8060408385031215612abe575f80fd5b612ac7836121ed565b9150602083015167ffffffffffffffff80821115612ae3575f80fd5b9084019060c08287031215612af6575f80fd5b612afe611ff1565b825182811115612b0c575f80fd5b612b188882860161298f565b825250612b27602084016124b5565b6020820152612b3860408401612351565b6040820152612b49606084016124b5565b6060820152608083015182811115612b5f575f80fd5b612b6b8882860161235c565b608083015250612b7d60a08401612351565b60a08201528093505050509250929050565b5f8060408385031215612ba0575f80fd5b612ba9836121ed565b9150602083015190509250929050565b5f805f8060808587031215612bcc575f80fd5b612bd5856121ed565b9350602085015167ffffffffffffffff80821115612bf1575f80fd5b612bfd88838901612728565b94506040870151915080821115612c12575f80fd5b612c1e888389016127e7565b93506060870151915080821115612c33575f80fd5b50612c40878288016128bb565b91505092959194509250565b5f8060408385031215612c5d575f80fd5b612c66836121ed565b9150612348602084016121ed565b5f8060408385031215612c85575f80fd5b612c8e836121ed565b9150602083015167ffffffffffffffff80821115612caa575f80fd5b9084019060408287031215612cbd575f80fd5b612cc5611faa565b825182811115612cd3575f80fd5b612cdf8882860161298f565b825250612cee602084016121ed565b60208201528093505050509250929050565b5f8060808385031215612d11575f80fd5b612d1a836121ed565b915061234884602085016125a7565b5f8060408385031215612d3a575f80fd5b612d43836121ed565b9150602083015167ffffffffffffffff811115612d5e575f80fd5b6124818582860161298f56fe90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aaa2646970667358221220b6799bbd2808a8d828ef80aab7feb21d287919944d72a3f8ca0c57ade7ebea0b64736f6c63430008180033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json index 64c12d493..970875ec9 100644 --- a/artifacts/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json +++ b/artifacts/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json @@ -93,6 +93,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "associateTokenPublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -197,6 +221,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantTokenKycPublic", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -523,8 +571,8 @@ "type": "function" } ], - "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a556114a8806101235f395ff3fe608060405234801561000f575f80fd5b50600436106100da575f3560e01c8063842b71db11610088578063cc2528f011610063578063cc2528f0146101bd578063df6c06f5146101d0578063f25b1200146101e3578063f848fec4146101f6575f80fd5b8063842b71db14610184578063970e23d2146101975780639b23d3d9146101aa575f80fd5b8063618dc65e116100b8578063618dc65e1461013d5780636c40a7771461015e5780636da6b1f014610171575f80fd5b806315dacbea146100de5780634ba6703514610109578063581315511461012a575b5f80fd5b6100f16100ec3660046109b0565b610209565b60405160079190910b81526020015b60405180910390f35b61011c610117366004610a09565b6102f8565b604051908152602001610100565b61011c610138366004610be8565b610354565b61015061014b366004610c57565b6103ae565b604051610100929190610d44565b6100f161016c3660046109b0565b6104c5565b61011c61017f366004610a09565b610590565b6100f16101923660046109b0565b61059d565b61011c6101a5366004610d5c565b6105e2565b6100f16101b83660046109b0565b6105fe565b61011c6101cb366004610df5565b610642565b61011c6101de366004610e88565b61064f565b61011c6101f1366004610ed0565b61065b565b61011c610204366004610e88565b610667565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516102879190610f10565b5f604051808303815f865af19150503d805f81146102c0576040519150601f19603f3d011682016040523d82523d5f602084013e6102c5565b606091505b5091509150816102d65760156102ea565b808060200190518101906102ea9190610f2b565b60030b979650505050505050565b5f61030585858585610673565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161033891815260200190565b60405180910390a16016811461034c575f80fd5b949350505050565b5f6103608484846106ba565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161039391815260200190565b60405180910390a1601681146103a7575f80fd5b9392505050565b5f60605f806101676001600160a01b031663618dc65e60e01b87876040516024016103da929190610f4b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516104189190610f10565b5f604051808303815f865af19150503d805f8114610451576040519150601f19603f3d011682016040523d82523d5f602084013e610456565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161048c929190610f6c565b60405180910390a1816104af57601560405180602001604052805f8152506104b3565b6016815b60039190910b97909650945050505050565b604051639b23d3d960e01b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f903090639b23d3d9906084015b6020604051808303815f875af1158015610522573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105469190610f86565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b60161461034c575f80fd5b5f61030585858585610794565b604051630aed65f560e11b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f9030906315dacbea90608401610506565b5f6103606105ef85611047565b6105f984866110a5565b6107db565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610249565b5f610305858585856108b2565b5f6103608484846108e0565b5f61036084848461091c565b5f610360848484610959565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610249565b5f805f6101676001600160a01b03166382bba49360e01b8787876040516024016106e693929190611295565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516107249190610f10565b5f604051808303815f865af19150503d805f811461075d576040519150601f19603f3d011682016040523d82523d5f602084013e610762565b606091505b509150915081610773576015610787565b808060200190518101906107879190610f2b565b60030b9695505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610249565b5f805f6101676001600160a01b0316630e71804f60e01b8686604051602401610805929190611325565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108439190610f10565b5f604051808303815f865af19150503d805f811461087c576040519150601f19603f3d011682016040523d82523d5f602084013e610881565b606091505b5091509150816108925760156108a6565b808060200190518101906108a69190610f2b565b60030b95945050505050565b5f805f6101676001600160a01b0316632c4ba19160e01b888888886040516024016102499493929190611420565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b906084016106e6565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b906084016106e6565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b906084016106e6565b80356001600160a01b03811681146109ab575f80fd5b919050565b5f805f80608085870312156109c3575f80fd5b6109cc85610995565b93506109da60208601610995565b92506109e860408601610995565b9396929550929360600135925050565b8060070b8114610a06575f80fd5b50565b5f805f8060808587031215610a1c575f80fd5b610a2585610995565b9350610a3360208601610995565b9250610a4160408601610995565b91506060850135610a51816109f8565b939692955090935050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715610a9357610a93610a5c565b60405290565b6040516080810167ffffffffffffffff81118282101715610a9357610a93610a5c565b604051601f8201601f1916810167ffffffffffffffff81118282101715610ae557610ae5610a5c565b604052919050565b5f67ffffffffffffffff821115610b0657610b06610a5c565b5060051b60200190565b5f82601f830112610b1f575f80fd5b81356020610b34610b2f83610aed565b610abc565b8083825260208201915060208460051b870101935086841115610b55575f80fd5b602086015b84811015610b7857610b6b81610995565b8352918301918301610b5a565b509695505050505050565b5f82601f830112610b92575f80fd5b81356020610ba2610b2f83610aed565b8083825260208201915060208460051b870101935086841115610bc3575f80fd5b602086015b84811015610b78578035610bdb816109f8565b8352918301918301610bc8565b5f805f60608486031215610bfa575f80fd5b610c0384610995565b9250602084013567ffffffffffffffff80821115610c1f575f80fd5b610c2b87838801610b10565b93506040860135915080821115610c40575f80fd5b50610c4d86828701610b83565b9150509250925092565b5f8060408385031215610c68575f80fd5b610c7183610995565b915060208084013567ffffffffffffffff80821115610c8e575f80fd5b818601915086601f830112610ca1575f80fd5b813581811115610cb357610cb3610a5c565b610cc5601f8201601f19168501610abc565b91508082528784828501011115610cda575f80fd5b80848401858401375f848284010152508093505050509250929050565b5f5b83811015610d11578181015183820152602001610cf9565b50505f910152565b5f8151808452610d30816020860160208601610cf7565b601f01601f19169290920160200192915050565b828152604060208201525f61034c6040830184610d19565b5f805f60408486031215610d6e575f80fd5b833567ffffffffffffffff80821115610d85575f80fd5b9085019060208288031215610d98575f80fd5b90935060208501359080821115610dad575f80fd5b818601915086601f830112610dc0575f80fd5b813581811115610dce575f80fd5b8760208260051b8501011115610de2575f80fd5b6020830194508093505050509250925092565b5f805f8060808587031215610e08575f80fd5b610e1185610995565b9350602085013567ffffffffffffffff80821115610e2d575f80fd5b610e3988838901610b10565b94506040870135915080821115610e4e575f80fd5b610e5a88838901610b10565b93506060870135915080821115610e6f575f80fd5b50610e7c87828801610b83565b91505092959194509250565b5f805f60608486031215610e9a575f80fd5b610ea384610995565b9250610eb160208501610995565b9150604084013590509250925092565b803580151581146109ab575f80fd5b5f805f60608486031215610ee2575f80fd5b610eeb84610995565b9250610ef960208501610995565b9150610f0760408501610ec1565b90509250925092565b5f8251610f21818460208701610cf7565b9190910192915050565b5f60208284031215610f3b575f80fd5b81518060030b81146103a7575f80fd5b6001600160a01b0383168152604060208201525f61034c6040830184610d19565b8215158152604060208201525f61034c6040830184610d19565b5f60208284031215610f96575f80fd5b81516103a7816109f8565b5f82601f830112610fb0575f80fd5b81356020610fc0610b2f83610aed565b82815260609283028501820192828201919087851115610fde575f80fd5b8387015b8581101561103a5781818a031215610ff8575f80fd5b611000610a70565b61100982610995565b815285820135611018816109f8565b818701526040611029838201610ec1565b908201528452928401928101610fe2565b5090979650505050505050565b5f60208236031215611057575f80fd5b6040516020810167ffffffffffffffff828210818311171561107b5761107b610a5c565b81604052843591508082111561108f575f80fd5b5061109c36828601610fa1565b82525092915050565b5f6110b2610b2f84610aed565b80848252602080830192508560051b8501368111156110cf575f80fd5b855b8181101561121457803567ffffffffffffffff808211156110f0575f80fd5b81890191506060808336031215611105575f80fd5b61110d610a70565b61111684610995565b81528684013583811115611128575f80fd5b61113436828701610fa1565b88830152506040808501358481111561114b575f80fd5b949094019336601f86011261115e575f80fd5b8435935061116e610b2f85610aed565b84815260079490941b8501880193888101903686111561118c575f80fd5b958901955b858710156111fc57608087360312156111a8575f80fd5b6111b0610a99565b6111b988610995565b81526111c68b8901610995565b8b820152838801356111d7816109f8565b818501526111e6888701610ec1565b8187015282526080969096019590890190611191565b918301919091525088525050509382019382016110d1565b50919695505050505050565b5f815180845260208085019450602084015f5b838110156112585781516001600160a01b031687529582019590820190600101611233565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561125857815160070b87529582019590820190600101611276565b6001600160a01b0384168152606060208201525f6112b66060830185611220565b82810360408401526112c88185611263565b9695505050505050565b5f815180845260208085019450602084015f5b8381101561125857815180516001600160a01b031688528381015160070b84890152604090810151151590880152606090960195908201906001016112e5565b5f6040808352606085516020808487015261134360608701836112d2565b9150858203818701528187518084528284019150828160051b850101838a015f5b8381101561140f57601f1987840301855281516001600160a01b03808251168552878201518a8987015261139a8b8701826112d2565b928c0151868403878e01528051808552908a01935f92508a01905b808310156113f95784518051851683528b81015185168c8401528e81015160070b8f8401528d015115158d830152938a0193600192909201916080909101906113b5565b5097890197955050509186019150600101611364565b50909b9a5050505050505050505050565b6001600160a01b0385168152608060208201525f6114416080830186611220565b82810360408401526114538186611220565b905082810360608401526114678185611263565b97965050505050505056fea2646970667358221220b604cc68645269a46f303768173f2ec616d8df76edad4a937d6165b171c8f17964736f6c63430008180033", - "deployedBytecode": "0x608060405234801561000f575f80fd5b50600436106100da575f3560e01c8063842b71db11610088578063cc2528f011610063578063cc2528f0146101bd578063df6c06f5146101d0578063f25b1200146101e3578063f848fec4146101f6575f80fd5b8063842b71db14610184578063970e23d2146101975780639b23d3d9146101aa575f80fd5b8063618dc65e116100b8578063618dc65e1461013d5780636c40a7771461015e5780636da6b1f014610171575f80fd5b806315dacbea146100de5780634ba6703514610109578063581315511461012a575b5f80fd5b6100f16100ec3660046109b0565b610209565b60405160079190910b81526020015b60405180910390f35b61011c610117366004610a09565b6102f8565b604051908152602001610100565b61011c610138366004610be8565b610354565b61015061014b366004610c57565b6103ae565b604051610100929190610d44565b6100f161016c3660046109b0565b6104c5565b61011c61017f366004610a09565b610590565b6100f16101923660046109b0565b61059d565b61011c6101a5366004610d5c565b6105e2565b6100f16101b83660046109b0565b6105fe565b61011c6101cb366004610df5565b610642565b61011c6101de366004610e88565b61064f565b61011c6101f1366004610ed0565b61065b565b61011c610204366004610e88565b610667565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516102879190610f10565b5f604051808303815f865af19150503d805f81146102c0576040519150601f19603f3d011682016040523d82523d5f602084013e6102c5565b606091505b5091509150816102d65760156102ea565b808060200190518101906102ea9190610f2b565b60030b979650505050505050565b5f61030585858585610673565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161033891815260200190565b60405180910390a16016811461034c575f80fd5b949350505050565b5f6103608484846106ba565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161039391815260200190565b60405180910390a1601681146103a7575f80fd5b9392505050565b5f60605f806101676001600160a01b031663618dc65e60e01b87876040516024016103da929190610f4b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516104189190610f10565b5f604051808303815f865af19150503d805f8114610451576040519150601f19603f3d011682016040523d82523d5f602084013e610456565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc828260405161048c929190610f6c565b60405180910390a1816104af57601560405180602001604052805f8152506104b3565b6016815b60039190910b97909650945050505050565b604051639b23d3d960e01b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f903090639b23d3d9906084015b6020604051808303815f875af1158015610522573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105469190610f86565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b60161461034c575f80fd5b5f61030585858585610794565b604051630aed65f560e11b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f9030906315dacbea90608401610506565b5f6103606105ef85611047565b6105f984866110a5565b6107db565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a401610249565b5f610305858585856108b2565b5f6103608484846108e0565b5f61036084848461091c565b5f610360848484610959565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a401610249565b5f805f6101676001600160a01b03166382bba49360e01b8787876040516024016106e693929190611295565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516107249190610f10565b5f604051808303815f865af19150503d805f811461075d576040519150601f19603f3d011682016040523d82523d5f602084013e610762565b606091505b509150915081610773576015610787565b808060200190518101906107879190610f2b565b60030b9695505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a401610249565b5f805f6101676001600160a01b0316630e71804f60e01b8686604051602401610805929190611325565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108439190610f10565b5f604051808303815f865af19150503d805f811461087c576040519150601f19603f3d011682016040523d82523d5f602084013e610881565b606091505b5091509150816108925760156108a6565b808060200190518101906108a69190610f2b565b60030b95945050505050565b5f805f6101676001600160a01b0316632c4ba19160e01b888888886040516024016102499493929190611420565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b906084016106e6565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b906084016106e6565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b906084016106e6565b80356001600160a01b03811681146109ab575f80fd5b919050565b5f805f80608085870312156109c3575f80fd5b6109cc85610995565b93506109da60208601610995565b92506109e860408601610995565b9396929550929360600135925050565b8060070b8114610a06575f80fd5b50565b5f805f8060808587031215610a1c575f80fd5b610a2585610995565b9350610a3360208601610995565b9250610a4160408601610995565b91506060850135610a51816109f8565b939692955090935050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715610a9357610a93610a5c565b60405290565b6040516080810167ffffffffffffffff81118282101715610a9357610a93610a5c565b604051601f8201601f1916810167ffffffffffffffff81118282101715610ae557610ae5610a5c565b604052919050565b5f67ffffffffffffffff821115610b0657610b06610a5c565b5060051b60200190565b5f82601f830112610b1f575f80fd5b81356020610b34610b2f83610aed565b610abc565b8083825260208201915060208460051b870101935086841115610b55575f80fd5b602086015b84811015610b7857610b6b81610995565b8352918301918301610b5a565b509695505050505050565b5f82601f830112610b92575f80fd5b81356020610ba2610b2f83610aed565b8083825260208201915060208460051b870101935086841115610bc3575f80fd5b602086015b84811015610b78578035610bdb816109f8565b8352918301918301610bc8565b5f805f60608486031215610bfa575f80fd5b610c0384610995565b9250602084013567ffffffffffffffff80821115610c1f575f80fd5b610c2b87838801610b10565b93506040860135915080821115610c40575f80fd5b50610c4d86828701610b83565b9150509250925092565b5f8060408385031215610c68575f80fd5b610c7183610995565b915060208084013567ffffffffffffffff80821115610c8e575f80fd5b818601915086601f830112610ca1575f80fd5b813581811115610cb357610cb3610a5c565b610cc5601f8201601f19168501610abc565b91508082528784828501011115610cda575f80fd5b80848401858401375f848284010152508093505050509250929050565b5f5b83811015610d11578181015183820152602001610cf9565b50505f910152565b5f8151808452610d30816020860160208601610cf7565b601f01601f19169290920160200192915050565b828152604060208201525f61034c6040830184610d19565b5f805f60408486031215610d6e575f80fd5b833567ffffffffffffffff80821115610d85575f80fd5b9085019060208288031215610d98575f80fd5b90935060208501359080821115610dad575f80fd5b818601915086601f830112610dc0575f80fd5b813581811115610dce575f80fd5b8760208260051b8501011115610de2575f80fd5b6020830194508093505050509250925092565b5f805f8060808587031215610e08575f80fd5b610e1185610995565b9350602085013567ffffffffffffffff80821115610e2d575f80fd5b610e3988838901610b10565b94506040870135915080821115610e4e575f80fd5b610e5a88838901610b10565b93506060870135915080821115610e6f575f80fd5b50610e7c87828801610b83565b91505092959194509250565b5f805f60608486031215610e9a575f80fd5b610ea384610995565b9250610eb160208501610995565b9150604084013590509250925092565b803580151581146109ab575f80fd5b5f805f60608486031215610ee2575f80fd5b610eeb84610995565b9250610ef960208501610995565b9150610f0760408501610ec1565b90509250925092565b5f8251610f21818460208701610cf7565b9190910192915050565b5f60208284031215610f3b575f80fd5b81518060030b81146103a7575f80fd5b6001600160a01b0383168152604060208201525f61034c6040830184610d19565b8215158152604060208201525f61034c6040830184610d19565b5f60208284031215610f96575f80fd5b81516103a7816109f8565b5f82601f830112610fb0575f80fd5b81356020610fc0610b2f83610aed565b82815260609283028501820192828201919087851115610fde575f80fd5b8387015b8581101561103a5781818a031215610ff8575f80fd5b611000610a70565b61100982610995565b815285820135611018816109f8565b818701526040611029838201610ec1565b908201528452928401928101610fe2565b5090979650505050505050565b5f60208236031215611057575f80fd5b6040516020810167ffffffffffffffff828210818311171561107b5761107b610a5c565b81604052843591508082111561108f575f80fd5b5061109c36828601610fa1565b82525092915050565b5f6110b2610b2f84610aed565b80848252602080830192508560051b8501368111156110cf575f80fd5b855b8181101561121457803567ffffffffffffffff808211156110f0575f80fd5b81890191506060808336031215611105575f80fd5b61110d610a70565b61111684610995565b81528684013583811115611128575f80fd5b61113436828701610fa1565b88830152506040808501358481111561114b575f80fd5b949094019336601f86011261115e575f80fd5b8435935061116e610b2f85610aed565b84815260079490941b8501880193888101903686111561118c575f80fd5b958901955b858710156111fc57608087360312156111a8575f80fd5b6111b0610a99565b6111b988610995565b81526111c68b8901610995565b8b820152838801356111d7816109f8565b818501526111e6888701610ec1565b8187015282526080969096019590890190611191565b918301919091525088525050509382019382016110d1565b50919695505050505050565b5f815180845260208085019450602084015f5b838110156112585781516001600160a01b031687529582019590820190600101611233565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561125857815160070b87529582019590820190600101611276565b6001600160a01b0384168152606060208201525f6112b66060830185611220565b82810360408401526112c88185611263565b9695505050505050565b5f815180845260208085019450602084015f5b8381101561125857815180516001600160a01b031688528381015160070b84890152604090810151151590880152606090960195908201906001016112e5565b5f6040808352606085516020808487015261134360608701836112d2565b9150858203818701528187518084528284019150828160051b850101838a015f5b8381101561140f57601f1987840301855281516001600160a01b03808251168552878201518a8987015261139a8b8701826112d2565b928c0151868403878e01528051808552908a01935f92508a01905b808310156113f95784518051851683528b81015185168c8401528e81015160070b8f8401528d015115158d830152938a0193600192909201916080909101906113b5565b5097890197955050509186019150600101611364565b50909b9a5050505050505050505050565b6001600160a01b0385168152608060208201525f6114416080830186611220565b82810360408401526114538186611220565b905082810360608401526114678185611263565b97965050505050505056fea2646970667358221220b604cc68645269a46f303768173f2ec616d8df76edad4a937d6165b171c8f17964736f6c63430008180033", + "bytecode": "0x608060405234801561000f575f80fd5b50600160208181527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb499190915560027fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f5560047fd9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330f5560087f7dfe757ecd65cbd7922a9c0161e935dd7fdbcc0e999689c7d31633896b1fc60b5560107fedc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643557fe2689cd4a84e23ad2f564004f1c9013e9589d260bde6380aba3ca7e09e4df40c5560065f5260407f8f331abe73332f95a25873e8b430885974c0409691f89d643119a11623a7924a55611628806101235f395ff3fe608060405234801561000f575f80fd5b50600436106100f0575f3560e01c8063842b71db11610093578063df6c06f511610063578063df6c06f5146101f9578063f25b12001461020c578063f4a01e5b1461021f578063f848fec414610232575f80fd5b8063842b71db146101ad578063970e23d2146101c05780639b23d3d9146101d3578063cc2528f0146101e6575f80fd5b806358131551116100ce5780635813155114610153578063618dc65e146101665780636c40a777146101875780636da6b1f01461019a575f80fd5b80630fd2601e146100f457806315dacbea1461011f5780634ba6703514610132575b5f80fd5b610107610102366004610aff565b610245565b60405160079190910b81526020015b60405180910390f35b61010761012d366004610b30565b6102a0565b610145610140366004610b89565b61038f565b604051908152602001610116565b610145610161366004610d68565b6103eb565b610179610174366004610dd7565b610445565b604051610116929190610ec4565b610107610195366004610b30565b61055c565b6101456101a8366004610b89565b610627565b6101076101bb366004610b30565b610634565b6101456101ce366004610edc565b610679565b6101076101e1366004610b30565b610695565b6101456101f4366004610f75565b6106d9565b610145610207366004611008565b6106e6565b61014561021a366004611050565b6106f2565b61014561022d366004610aff565b6106fe565b610145610240366004611008565b610750565b5f610250838361075c565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b60161461029a575f80fd5b92915050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161031e9190611090565b5f604051808303815f865af19150503d805f8114610357576040519150601f19603f3d011682016040523d82523d5f602084013e61035c565b606091505b50915091508161036d576015610381565b8080602001905181019061038191906110ab565b60030b979650505050505050565b5f61039c8585858561083a565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa816040516103cf91815260200190565b60405180910390a1601681146103e3575f80fd5b949350505050565b5f6103f7848484610881565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161042a91815260200190565b60405180910390a16016811461043e575f80fd5b9392505050565b5f60605f806101676001600160a01b031663618dc65e60e01b87876040516024016104719291906110cb565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516104af9190611090565b5f604051808303815f865af19150503d805f81146104e8576040519150601f19603f3d011682016040523d82523d5f602084013e6104ed565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc82826040516105239291906110ec565b60405180910390a18161054657601560405180602001604052805f81525061054a565b6016815b60039190910b97909650945050505050565b604051639b23d3d960e01b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f903090639b23d3d9906084015b6020604051808303815f875af11580156105b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105dd9190611106565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146103e3575f80fd5b5f61039c8585858561095b565b604051630aed65f560e11b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f9030906315dacbea9060840161059d565b5f6103f7610686856111c7565b6106908486611225565b6109a2565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a4016102e0565b5f61039c858585856109cc565b5f6103f78484846109fa565b5f6103f7848484610a36565b5f6107098383610a73565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161073c91815260200190565b60405180910390a16016811461029a575f80fd5b5f6103f7848484610aa8565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516107cb9190611090565b5f604051808303815f865af19150503d805f8114610804576040519150601f19603f3d011682016040523d82523d5f602084013e610809565b606091505b50915091508161081a57601561082e565b8080602001905181019061082e91906110ab565b60030b95945050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a4016102e0565b5f805f6101676001600160a01b03166382bba49360e01b8787876040516024016108ad93929190611415565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108eb9190611090565b5f604051808303815f865af19150503d805f8114610924576040519150601f19603f3d011682016040523d82523d5f602084013e610929565b606091505b50915091508161093a57601561094e565b8080602001905181019061094e91906110ab565b60030b9695505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a4016102e0565b5f805f6101676001600160a01b0316630e71804f60e01b868660405160240161078d9291906114a5565b5f805f6101676001600160a01b0316632c4ba19160e01b888888886040516024016102e094939291906115a0565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b906084016108ad565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b906084016108ad565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b9060640161078d565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b906084016108ad565b80356001600160a01b0381168114610afa575f80fd5b919050565b5f8060408385031215610b10575f80fd5b610b1983610ae4565b9150610b2760208401610ae4565b90509250929050565b5f805f8060808587031215610b43575f80fd5b610b4c85610ae4565b9350610b5a60208601610ae4565b9250610b6860408601610ae4565b9396929550929360600135925050565b8060070b8114610b86575f80fd5b50565b5f805f8060808587031215610b9c575f80fd5b610ba585610ae4565b9350610bb360208601610ae4565b9250610bc160408601610ae4565b91506060850135610bd181610b78565b939692955090935050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715610c1357610c13610bdc565b60405290565b6040516080810167ffffffffffffffff81118282101715610c1357610c13610bdc565b604051601f8201601f1916810167ffffffffffffffff81118282101715610c6557610c65610bdc565b604052919050565b5f67ffffffffffffffff821115610c8657610c86610bdc565b5060051b60200190565b5f82601f830112610c9f575f80fd5b81356020610cb4610caf83610c6d565b610c3c565b8083825260208201915060208460051b870101935086841115610cd5575f80fd5b602086015b84811015610cf857610ceb81610ae4565b8352918301918301610cda565b509695505050505050565b5f82601f830112610d12575f80fd5b81356020610d22610caf83610c6d565b8083825260208201915060208460051b870101935086841115610d43575f80fd5b602086015b84811015610cf8578035610d5b81610b78565b8352918301918301610d48565b5f805f60608486031215610d7a575f80fd5b610d8384610ae4565b9250602084013567ffffffffffffffff80821115610d9f575f80fd5b610dab87838801610c90565b93506040860135915080821115610dc0575f80fd5b50610dcd86828701610d03565b9150509250925092565b5f8060408385031215610de8575f80fd5b610df183610ae4565b915060208084013567ffffffffffffffff80821115610e0e575f80fd5b818601915086601f830112610e21575f80fd5b813581811115610e3357610e33610bdc565b610e45601f8201601f19168501610c3c565b91508082528784828501011115610e5a575f80fd5b80848401858401375f848284010152508093505050509250929050565b5f5b83811015610e91578181015183820152602001610e79565b50505f910152565b5f8151808452610eb0816020860160208601610e77565b601f01601f19169290920160200192915050565b828152604060208201525f6103e36040830184610e99565b5f805f60408486031215610eee575f80fd5b833567ffffffffffffffff80821115610f05575f80fd5b9085019060208288031215610f18575f80fd5b90935060208501359080821115610f2d575f80fd5b818601915086601f830112610f40575f80fd5b813581811115610f4e575f80fd5b8760208260051b8501011115610f62575f80fd5b6020830194508093505050509250925092565b5f805f8060808587031215610f88575f80fd5b610f9185610ae4565b9350602085013567ffffffffffffffff80821115610fad575f80fd5b610fb988838901610c90565b94506040870135915080821115610fce575f80fd5b610fda88838901610c90565b93506060870135915080821115610fef575f80fd5b50610ffc87828801610d03565b91505092959194509250565b5f805f6060848603121561101a575f80fd5b61102384610ae4565b925061103160208501610ae4565b9150604084013590509250925092565b80358015158114610afa575f80fd5b5f805f60608486031215611062575f80fd5b61106b84610ae4565b925061107960208501610ae4565b915061108760408501611041565b90509250925092565b5f82516110a1818460208701610e77565b9190910192915050565b5f602082840312156110bb575f80fd5b81518060030b811461043e575f80fd5b6001600160a01b0383168152604060208201525f6103e36040830184610e99565b8215158152604060208201525f6103e36040830184610e99565b5f60208284031215611116575f80fd5b815161043e81610b78565b5f82601f830112611130575f80fd5b81356020611140610caf83610c6d565b8281526060928302850182019282820191908785111561115e575f80fd5b8387015b858110156111ba5781818a031215611178575f80fd5b611180610bf0565b61118982610ae4565b81528582013561119881610b78565b8187015260406111a9838201611041565b908201528452928401928101611162565b5090979650505050505050565b5f602082360312156111d7575f80fd5b6040516020810167ffffffffffffffff82821081831117156111fb576111fb610bdc565b81604052843591508082111561120f575f80fd5b5061121c36828601611121565b82525092915050565b5f611232610caf84610c6d565b80848252602080830192508560051b85013681111561124f575f80fd5b855b8181101561139457803567ffffffffffffffff80821115611270575f80fd5b81890191506060808336031215611285575f80fd5b61128d610bf0565b61129684610ae4565b815286840135838111156112a8575f80fd5b6112b436828701611121565b8883015250604080850135848111156112cb575f80fd5b949094019336601f8601126112de575f80fd5b843593506112ee610caf85610c6d565b84815260079490941b8501880193888101903686111561130c575f80fd5b958901955b8587101561137c5760808736031215611328575f80fd5b611330610c19565b61133988610ae4565b81526113468b8901610ae4565b8b8201528388013561135781610b78565b81850152611366888701611041565b8187015282526080969096019590890190611311565b91830191909152508852505050938201938201611251565b50919695505050505050565b5f815180845260208085019450602084015f5b838110156113d85781516001600160a01b0316875295820195908201906001016113b3565b509495945050505050565b5f815180845260208085019450602084015f5b838110156113d857815160070b875295820195908201906001016113f6565b6001600160a01b0384168152606060208201525f61143660608301856113a0565b828103604084015261144881856113e3565b9695505050505050565b5f815180845260208085019450602084015f5b838110156113d857815180516001600160a01b031688528381015160070b8489015260409081015115159088015260609096019590820190600101611465565b5f604080835260608551602080848701526114c36060870183611452565b9150858203818701528187518084528284019150828160051b850101838a015f5b8381101561158f57601f1987840301855281516001600160a01b03808251168552878201518a8987015261151a8b870182611452565b928c0151868403878e01528051808552908a01935f92508a01905b808310156115795784518051851683528b81015185168c8401528e81015160070b8f8401528d015115158d830152938a019360019290920191608090910190611535565b50978901979550505091860191506001016114e4565b50909b9a5050505050505050505050565b6001600160a01b0385168152608060208201525f6115c160808301866113a0565b82810360408401526115d381866113a0565b905082810360608401526115e781856113e3565b97965050505050505056fea2646970667358221220cf1c731b3507b39f2bacab51733172f2a1ed4e4db118b8080a7abbd74b475f1364736f6c63430008180033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b50600436106100f0575f3560e01c8063842b71db11610093578063df6c06f511610063578063df6c06f5146101f9578063f25b12001461020c578063f4a01e5b1461021f578063f848fec414610232575f80fd5b8063842b71db146101ad578063970e23d2146101c05780639b23d3d9146101d3578063cc2528f0146101e6575f80fd5b806358131551116100ce5780635813155114610153578063618dc65e146101665780636c40a777146101875780636da6b1f01461019a575f80fd5b80630fd2601e146100f457806315dacbea1461011f5780634ba6703514610132575b5f80fd5b610107610102366004610aff565b610245565b60405160079190910b81526020015b60405180910390f35b61010761012d366004610b30565b6102a0565b610145610140366004610b89565b61038f565b604051908152602001610116565b610145610161366004610d68565b6103eb565b610179610174366004610dd7565b610445565b604051610116929190610ec4565b610107610195366004610b30565b61055c565b6101456101a8366004610b89565b610627565b6101076101bb366004610b30565b610634565b6101456101ce366004610edc565b610679565b6101076101e1366004610b30565b610695565b6101456101f4366004610f75565b6106d9565b610145610207366004611008565b6106e6565b61014561021a366004611050565b6106f2565b61014561022d366004610aff565b6106fe565b610145610240366004611008565b610750565b5f610250838361075c565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b60161461029a575f80fd5b92915050565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790630aed65f560e11b9060a4015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161031e9190611090565b5f604051808303815f865af19150503d805f8114610357576040519150601f19603f3d011682016040523d82523d5f602084013e61035c565b606091505b50915091508161036d576015610381565b8080602001905181019061038191906110ab565b60030b979650505050505050565b5f61039c8585858561083a565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa816040516103cf91815260200190565b60405180910390a1601681146103e3575f80fd5b949350505050565b5f6103f7848484610881565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161042a91815260200190565b60405180910390a16016811461043e575f80fd5b9392505050565b5f60605f806101676001600160a01b031663618dc65e60e01b87876040516024016104719291906110cb565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516104af9190611090565b5f604051808303815f865af19150503d805f81146104e8576040519150601f19603f3d011682016040523d82523d5f602084013e6104ed565b606091505b50915091507f4af4780e06fe8cb9df64b0794fa6f01399af979175bb988e35e0e57e594567bc82826040516105239291906110ec565b60405180910390a18161054657601560405180602001604052805f81525061054a565b6016815b60039190910b97909650945050505050565b604051639b23d3d960e01b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f903090639b23d3d9906084015b6020604051808303815f875af11580156105b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105dd9190611106565b604051600782900b81529091507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa9060200160405180910390a1600781900b6016146103e3575f80fd5b5f61039c8585858561095b565b604051630aed65f560e11b81526001600160a01b038086166004830152808516602483015283166044820152606481018290525f9030906315dacbea9060840161059d565b5f6103f7610686856111c7565b6106908486611225565b6109a2565b6040516001600160a01b038581166024830152848116604483015283166064820152608481018290525f908190819061016790639b23d3d960e01b9060a4016102e0565b5f61039c858585856109cc565b5f6103f78484846109fa565b5f6103f7848484610a36565b5f6107098383610a73565b90507f90a5cf4cffe88b4edbb041cfc7a8a812c48a5ec30b84640fb37690875168e3aa8160405161073c91815260200190565b60405180910390a16016811461029a575f80fd5b5f6103f7848484610aa8565b6040516001600160a01b038381166024830152821660448201525f908190819061016790638f8d7f9960e01b906064015b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516107cb9190611090565b5f604051808303815f865af19150503d805f8114610804576040519150601f19603f3d011682016040523d82523d5f602084013e610809565b606091505b50915091508161081a57601561082e565b8080602001905181019061082e91906110ab565b60030b95945050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f90819081906101679063eca3691760e01b9060a4016102e0565b5f805f6101676001600160a01b03166382bba49360e01b8787876040516024016108ad93929190611415565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516108eb9190611090565b5f604051808303815f865af19150503d805f8114610924576040519150601f19603f3d011682016040523d82523d5f602084013e610929565b606091505b50915091508161093a57601561094e565b8080602001905181019061094e91906110ab565b60030b9695505050505050565b6040516001600160a01b038581166024830152848116604483015283166064820152600782900b60848201525f908190819061016790635cfc901160e01b9060a4016102e0565b5f805f6101676001600160a01b0316630e71804f60e01b868660405160240161078d9291906114a5565b5f805f6101676001600160a01b0316632c4ba19160e01b888888886040516024016102e094939291906115a0565b6040516001600160a01b03848116602483015283166044820152606481018290525f9081908190610167906307336aaf60e41b906084016108ad565b6040516001600160a01b0384811660248301528316604482015281151560648201525f908190819061016790631b3b02e560e11b906084016108ad565b6040516001600160a01b038381166024830152821660448201525f90819081906101679063248a35ef60e11b9060640161078d565b6040516001600160a01b03848116602483015283166044820152606481018290525f90819081906101679063e1f21c6760e01b906084016108ad565b80356001600160a01b0381168114610afa575f80fd5b919050565b5f8060408385031215610b10575f80fd5b610b1983610ae4565b9150610b2760208401610ae4565b90509250929050565b5f805f8060808587031215610b43575f80fd5b610b4c85610ae4565b9350610b5a60208601610ae4565b9250610b6860408601610ae4565b9396929550929360600135925050565b8060070b8114610b86575f80fd5b50565b5f805f8060808587031215610b9c575f80fd5b610ba585610ae4565b9350610bb360208601610ae4565b9250610bc160408601610ae4565b91506060850135610bd181610b78565b939692955090935050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715610c1357610c13610bdc565b60405290565b6040516080810167ffffffffffffffff81118282101715610c1357610c13610bdc565b604051601f8201601f1916810167ffffffffffffffff81118282101715610c6557610c65610bdc565b604052919050565b5f67ffffffffffffffff821115610c8657610c86610bdc565b5060051b60200190565b5f82601f830112610c9f575f80fd5b81356020610cb4610caf83610c6d565b610c3c565b8083825260208201915060208460051b870101935086841115610cd5575f80fd5b602086015b84811015610cf857610ceb81610ae4565b8352918301918301610cda565b509695505050505050565b5f82601f830112610d12575f80fd5b81356020610d22610caf83610c6d565b8083825260208201915060208460051b870101935086841115610d43575f80fd5b602086015b84811015610cf8578035610d5b81610b78565b8352918301918301610d48565b5f805f60608486031215610d7a575f80fd5b610d8384610ae4565b9250602084013567ffffffffffffffff80821115610d9f575f80fd5b610dab87838801610c90565b93506040860135915080821115610dc0575f80fd5b50610dcd86828701610d03565b9150509250925092565b5f8060408385031215610de8575f80fd5b610df183610ae4565b915060208084013567ffffffffffffffff80821115610e0e575f80fd5b818601915086601f830112610e21575f80fd5b813581811115610e3357610e33610bdc565b610e45601f8201601f19168501610c3c565b91508082528784828501011115610e5a575f80fd5b80848401858401375f848284010152508093505050509250929050565b5f5b83811015610e91578181015183820152602001610e79565b50505f910152565b5f8151808452610eb0816020860160208601610e77565b601f01601f19169290920160200192915050565b828152604060208201525f6103e36040830184610e99565b5f805f60408486031215610eee575f80fd5b833567ffffffffffffffff80821115610f05575f80fd5b9085019060208288031215610f18575f80fd5b90935060208501359080821115610f2d575f80fd5b818601915086601f830112610f40575f80fd5b813581811115610f4e575f80fd5b8760208260051b8501011115610f62575f80fd5b6020830194508093505050509250925092565b5f805f8060808587031215610f88575f80fd5b610f9185610ae4565b9350602085013567ffffffffffffffff80821115610fad575f80fd5b610fb988838901610c90565b94506040870135915080821115610fce575f80fd5b610fda88838901610c90565b93506060870135915080821115610fef575f80fd5b50610ffc87828801610d03565b91505092959194509250565b5f805f6060848603121561101a575f80fd5b61102384610ae4565b925061103160208501610ae4565b9150604084013590509250925092565b80358015158114610afa575f80fd5b5f805f60608486031215611062575f80fd5b61106b84610ae4565b925061107960208501610ae4565b915061108760408501611041565b90509250925092565b5f82516110a1818460208701610e77565b9190910192915050565b5f602082840312156110bb575f80fd5b81518060030b811461043e575f80fd5b6001600160a01b0383168152604060208201525f6103e36040830184610e99565b8215158152604060208201525f6103e36040830184610e99565b5f60208284031215611116575f80fd5b815161043e81610b78565b5f82601f830112611130575f80fd5b81356020611140610caf83610c6d565b8281526060928302850182019282820191908785111561115e575f80fd5b8387015b858110156111ba5781818a031215611178575f80fd5b611180610bf0565b61118982610ae4565b81528582013561119881610b78565b8187015260406111a9838201611041565b908201528452928401928101611162565b5090979650505050505050565b5f602082360312156111d7575f80fd5b6040516020810167ffffffffffffffff82821081831117156111fb576111fb610bdc565b81604052843591508082111561120f575f80fd5b5061121c36828601611121565b82525092915050565b5f611232610caf84610c6d565b80848252602080830192508560051b85013681111561124f575f80fd5b855b8181101561139457803567ffffffffffffffff80821115611270575f80fd5b81890191506060808336031215611285575f80fd5b61128d610bf0565b61129684610ae4565b815286840135838111156112a8575f80fd5b6112b436828701611121565b8883015250604080850135848111156112cb575f80fd5b949094019336601f8601126112de575f80fd5b843593506112ee610caf85610c6d565b84815260079490941b8501880193888101903686111561130c575f80fd5b958901955b8587101561137c5760808736031215611328575f80fd5b611330610c19565b61133988610ae4565b81526113468b8901610ae4565b8b8201528388013561135781610b78565b81850152611366888701611041565b8187015282526080969096019590890190611311565b91830191909152508852505050938201938201611251565b50919695505050505050565b5f815180845260208085019450602084015f5b838110156113d85781516001600160a01b0316875295820195908201906001016113b3565b509495945050505050565b5f815180845260208085019450602084015f5b838110156113d857815160070b875295820195908201906001016113f6565b6001600160a01b0384168152606060208201525f61143660608301856113a0565b828103604084015261144881856113e3565b9695505050505050565b5f815180845260208085019450602084015f5b838110156113d857815180516001600160a01b031688528381015160070b8489015260409081015115159088015260609096019590820190600101611465565b5f604080835260608551602080848701526114c36060870183611452565b9150858203818701528187518084528284019150828160051b850101838a015f5b8381101561158f57601f1987840301855281516001600160a01b03808251168552878201518a8987015261151a8b870182611452565b928c0151868403878e01528051808552908a01935f92508a01905b808310156115795784518051851683528b81015185168c8401528e81015160070b8f8401528d015115158d830152938a019360019290920191608090910190611535565b50978901979550505091860191506001016114e4565b50909b9a5050505050505050505050565b6001600160a01b0385168152608060208201525f6115c160808301866113a0565b82810360408401526115d381866113a0565b905082810360608401526115e781856113e3565b97965050505050505056fea2646970667358221220cf1c731b3507b39f2bacab51733172f2a1ed4e4db118b8080a7abbd74b475f1364736f6c63430008180033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts-abi/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol/IHederaTokenService.json b/contracts-abi/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol/IHederaTokenService.json index 9043249f5..d60dc3fe2 100644 --- a/contracts-abi/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol/IHederaTokenService.json +++ b/contracts-abi/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol/IHederaTokenService.json @@ -2723,6 +2723,182 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "minimumAmount", + "type": "int64" + }, + { + "internalType": "int64", + "name": "maximumAmount", + "type": "int64" + }, + { + "internalType": "bool", + "name": "netOfTransfers", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FractionalFee[]", + "name": "fractionalFees", + "type": "tuple[]" + } + ], + "name": "updateFungibleTokenCustomFees", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.RoyaltyFee[]", + "name": "royaltyFees", + "type": "tuple[]" + } + ], + "name": "updateNonFungibleTokenCustomFees", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json b/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json index 09490c2c0..9dda2ec9a 100644 --- a/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json +++ b/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol/TokenCreateCustomContract.json @@ -88,6 +88,35 @@ "name": "TransferToken", "type": "event" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approvePublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -235,11 +264,6 @@ "name": "treasury", "type": "address" }, - { - "internalType": "address", - "name": "fixedFeeTokenAddress", - "type": "address" - }, { "internalType": "string", "name": "name", @@ -271,9 +295,73 @@ "type": "int32" }, { - "internalType": "int64", - "name": "feeAmount", - "type": "int64" + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "minimumAmount", + "type": "int64" + }, + { + "internalType": "int64", + "name": "maximumAmount", + "type": "int64" + }, + { + "internalType": "bool", + "name": "netOfTransfers", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FractionalFee[]", + "name": "fractionalFees", + "type": "tuple[]" }, { "components": [ @@ -325,6 +413,54 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + }, + { + "internalType": "string", + "name": "memo", + "type": "string" + }, + { + "internalType": "int64", + "name": "initialTotalSupply", + "type": "int64" + }, + { + "internalType": "int64", + "name": "maxSupply", + "type": "int64" + }, + { + "internalType": "int32", + "name": "decimals", + "type": "int32" + }, + { + "internalType": "bool", + "name": "freezeDefaultStatus", + "type": "bool" + }, + { + "internalType": "address", + "name": "treasury", + "type": "address" + } + ], + "name": "createFungibleTokenWithPresetKeys", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -409,11 +545,6 @@ "name": "treasury", "type": "address" }, - { - "internalType": "address", - "name": "fixedFeeTokenAddress", - "type": "address" - }, { "internalType": "string", "name": "name", @@ -435,9 +566,73 @@ "type": "int64" }, { - "internalType": "int64", - "name": "feeAmount", - "type": "int64" + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.RoyaltyFee[]", + "name": "royaltyFees", + "type": "tuple[]" }, { "components": [ diff --git a/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json b/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json index dfc3eabb7..ef0e26d51 100644 --- a/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json +++ b/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol/TokenManagementContract.json @@ -452,6 +452,182 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "minimumAmount", + "type": "int64" + }, + { + "internalType": "int64", + "name": "maximumAmount", + "type": "int64" + }, + { + "internalType": "bool", + "name": "netOfTransfers", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FractionalFee[]", + "name": "fractionalFees", + "type": "tuple[]" + } + ], + "name": "updateFungibleTokenCustomFeesPublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "components": [ + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "bool", + "name": "useCurrentTokenForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.FixedFee[]", + "name": "fixedFees", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "int64", + "name": "numerator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "denominator", + "type": "int64" + }, + { + "internalType": "int64", + "name": "amount", + "type": "int64" + }, + { + "internalType": "address", + "name": "tokenId", + "type": "address" + }, + { + "internalType": "bool", + "name": "useHbarsForPayment", + "type": "bool" + }, + { + "internalType": "address", + "name": "feeCollector", + "type": "address" + } + ], + "internalType": "struct IHederaTokenService.RoyaltyFee[]", + "name": "royaltyFees", + "type": "tuple[]" + } + ], + "name": "updateNonFungibleTokenCustomFeesPublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json b/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json index 66c27a3cf..5ba7182e8 100644 --- a/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json +++ b/contracts-abi/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol/TokenTransferContract.json @@ -89,6 +89,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "associateTokenPublic", + "outputs": [ + { + "internalType": "int256", + "name": "responseCode", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -193,6 +217,30 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantTokenKycPublic", + "outputs": [ + { + "internalType": "int64", + "name": "responseCode", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/contracts/system-contracts/hedera-token-service/HederaTokenService.sol b/contracts/system-contracts/hedera-token-service/HederaTokenService.sol index d2a7def54..92f47946d 100644 --- a/contracts/system-contracts/hedera-token-service/HederaTokenService.sol +++ b/contracts/system-contracts/hedera-token-service/HederaTokenService.sol @@ -682,4 +682,26 @@ abstract contract HederaTokenService { emit CallResponseEvent(success, result); (responseCode, response) = success ? (HederaResponseCodes.SUCCESS, result) : (HederaResponseCodes.UNKNOWN, bytes("")); } + + /// Update the custom fees for a fungible token + /// @param token The token address + /// @param fixedFees Set of fixed fees for `token` + /// @param fractionalFees Set of fractional fees for `token` + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + function updateFungibleTokenCustomFees(address token, IHederaTokenService.FixedFee[] memory fixedFees, IHederaTokenService.FractionalFee[] memory fractionalFees) internal returns (int64 responseCode) { + (bool success, bytes memory result) = precompileAddress.call( + abi.encodeWithSelector(IHederaTokenService.updateFungibleTokenCustomFees.selector, token, fixedFees, fractionalFees)); + responseCode = success ? abi.decode(result, (int32)) : HederaResponseCodes.UNKNOWN; + } + + /// Update the custom fees for a non-fungible token + /// @param token The token address + /// @param fixedFees Set of fixed fees for `token` + /// @param royaltyFees Set of royalty fees for `token` + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + function updateNonFungibleTokenCustomFees(address token, IHederaTokenService.FixedFee[] memory fixedFees, IHederaTokenService.RoyaltyFee[] memory royaltyFees) internal returns (int64 responseCode) { + (bool success, bytes memory result) = precompileAddress.call( + abi.encodeWithSelector(IHederaTokenService.updateNonFungibleTokenCustomFees.selector, token, fixedFees, royaltyFees)); + responseCode = success ? abi.decode(result, (int32)) : HederaResponseCodes.UNKNOWN; + } } diff --git a/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol b/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol index 3a7327d0c..7cfed6928 100644 --- a/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol +++ b/contracts/system-contracts/hedera-token-service/IHederaTokenService.sol @@ -801,4 +801,18 @@ interface IHederaTokenService { /// @return responseCode The response code for the status of the request. SUCCESS is 22. /// @return response The result of the call that had been encoded and sent for execution. function redirectForToken(address token, bytes memory encodedFunctionSelector) external returns (int64 responseCode, bytes memory response); + + /// Update the custom fees for a fungible token + /// @param token The token address + /// @param fixedFees Set of fixed fees for `token` + /// @param fractionalFees Set of fractional fees for `token` + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + function updateFungibleTokenCustomFees(address token, IHederaTokenService.FixedFee[] memory fixedFees, IHederaTokenService.FractionalFee[] memory fractionalFees) external returns (int64 responseCode); + + /// Update the custom fees for a non-fungible token + /// @param token The token address + /// @param fixedFees Set of fixed fees for `token` + /// @param royaltyFees Set of royalty fees for `token` + /// @return responseCode The response code for the status of the request. SUCCESS is 22. + function updateNonFungibleTokenCustomFees(address token, IHederaTokenService.FixedFee[] memory fixedFees, IHederaTokenService.RoyaltyFee[] memory royaltyFees) external returns (int64 responseCode); } diff --git a/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol b/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol index eae2ddc7e..1d1155b56 100644 --- a/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol +++ b/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateContract.sol @@ -11,9 +11,9 @@ contract TokenCreateContract is HederaTokenService, ExpiryHelper, KeyHelper { string name = "tokenName"; string symbol = "tokenSymbol"; string memo = "memo"; - int64 initialTotalSupply = 1000; - int64 maxSupply = 10000; - int32 decimals = 8; + int64 initialTotalSupply = 10000000000; + int64 maxSupply = 20000000000; + int32 decimals = 0; bool freezeDefaultStatus = false; event ResponseCode(int responseCode); @@ -24,12 +24,13 @@ contract TokenCreateContract is HederaTokenService, ExpiryHelper, KeyHelper { function createFungibleTokenPublic( address treasury ) public payable { - IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](5); + IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](6); keys[0] = getSingleKey(KeyType.ADMIN, KeyType.PAUSE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); keys[1] = getSingleKey(KeyType.KYC, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); keys[2] = getSingleKey(KeyType.FREEZE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); keys[3] = getSingleKey(KeyType.WIPE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); keys[4] = getSingleKey(KeyType.SUPPLY, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); + keys[5] = getSingleKey(KeyType.FEE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); IHederaTokenService.Expiry memory expiry = IHederaTokenService.Expiry( 0, treasury, 8000000 @@ -52,12 +53,13 @@ contract TokenCreateContract is HederaTokenService, ExpiryHelper, KeyHelper { function createFungibleTokenWithSECP256K1AdminKeyPublic( address treasury, bytes memory adminKey ) public payable returns (address) { - IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](5); + IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](6); keys[0] = getSingleKey(KeyType.ADMIN, KeyType.PAUSE, KeyValueType.SECP256K1, adminKey); keys[1] = getSingleKey(KeyType.KYC, KeyValueType.SECP256K1, adminKey); keys[2] = getSingleKey(KeyType.FREEZE, KeyValueType.SECP256K1, adminKey); keys[3] = getSingleKey(KeyType.SUPPLY, KeyValueType.SECP256K1, adminKey); keys[4] = getSingleKey(KeyType.WIPE, KeyValueType.SECP256K1, adminKey); + keys[5] = getSingleKey(KeyType.FEE, KeyValueType.SECP256K1, adminKey); IHederaTokenService.Expiry memory expiry = IHederaTokenService.Expiry( 0, treasury, 8000000 @@ -178,12 +180,13 @@ contract TokenCreateContract is HederaTokenService, ExpiryHelper, KeyHelper { function createNonFungibleTokenWithSECP256K1AdminKeyPublic( address treasury, bytes memory adminKey ) public payable { - IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](5); + IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](6); keys[0] = getSingleKey(KeyType.ADMIN, KeyType.PAUSE, KeyValueType.SECP256K1, adminKey); keys[1] = getSingleKey(KeyType.KYC, KeyValueType.SECP256K1, adminKey); keys[2] = getSingleKey(KeyType.FREEZE, KeyValueType.SECP256K1, adminKey); keys[3] = getSingleKey(KeyType.SUPPLY, KeyValueType.SECP256K1, adminKey); keys[4] = getSingleKey(KeyType.WIPE, KeyValueType.SECP256K1, adminKey); + keys[5] = getSingleKey(KeyType.FEE, KeyValueType.SECP256K1, adminKey); IHederaTokenService.Expiry memory expiry = IHederaTokenService.Expiry( 0, treasury, 8000000 diff --git a/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol b/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol index 03d94d2e3..29f84a489 100644 --- a/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol +++ b/contracts/system-contracts/hedera-token-service/examples/token-create/TokenCreateCustom.sol @@ -5,9 +5,9 @@ pragma experimental ABIEncoderV2; import "../../HederaTokenService.sol"; import "../../ExpiryHelper.sol"; import "../../KeyHelper.sol"; +import "../../FeeHelper.sol"; -contract TokenCreateCustomContract is HederaTokenService, ExpiryHelper, KeyHelper { - +contract TokenCreateCustomContract is HederaTokenService, ExpiryHelper, KeyHelper, FeeHelper { event ResponseCode(int responseCode); event CreatedToken(address tokenAddress); event TransferToken(address tokenAddress, address receiver, int64 amount); @@ -41,16 +41,51 @@ contract TokenCreateCustomContract is HederaTokenService, ExpiryHelper, KeyHelpe emit CreatedToken(tokenAddress); } + function createFungibleTokenWithPresetKeys( + string memory name, + string memory symbol, + string memory memo, + int64 initialTotalSupply, + int64 maxSupply, + int32 decimals, + bool freezeDefaultStatus, + address treasury + ) public payable { + IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](6); + keys[0] = getSingleKey(KeyType.ADMIN, KeyType.PAUSE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); + keys[1] = getSingleKey(KeyType.KYC, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); + keys[2] = getSingleKey(KeyType.FREEZE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); + keys[3] = getSingleKey(KeyType.WIPE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); + keys[4] = getSingleKey(KeyType.SUPPLY, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); + keys[5] = getSingleKey(KeyType.FEE, KeyValueType.INHERIT_ACCOUNT_KEY, bytes("")); + + IHederaTokenService.Expiry memory expiry = IHederaTokenService.Expiry( + 0, treasury, 8000000 + ); + + IHederaTokenService.HederaToken memory token = IHederaTokenService.HederaToken( + name, symbol, treasury, memo, true, maxSupply, freezeDefaultStatus, keys, expiry + ); + + (int responseCode, address tokenAddress) = + HederaTokenService.createFungibleToken(token, initialTotalSupply, decimals); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert (); + } + emit CreatedToken(tokenAddress); + } + function createFungibleTokenWithCustomFeesPublic( address treasury, - address fixedFeeTokenAddress, string memory name, string memory symbol, string memory memo, int64 initialTotalSupply, int64 maxSupply, int32 decimals, - int64 feeAmount, + IHederaTokenService.FixedFee[] memory fixedFees, + IHederaTokenService.FractionalFee[] memory fractionalFees, IHederaTokenService.TokenKey[] memory keys ) public payable { IHederaTokenService.Expiry memory expiry = IHederaTokenService.Expiry( @@ -61,12 +96,6 @@ contract TokenCreateCustomContract is HederaTokenService, ExpiryHelper, KeyHelpe name, symbol, treasury, memo, true, maxSupply, false, keys, expiry ); - IHederaTokenService.FixedFee[] memory fixedFees = new IHederaTokenService.FixedFee[](1); - fixedFees[0] = IHederaTokenService.FixedFee(feeAmount, fixedFeeTokenAddress, false, false, treasury); - - IHederaTokenService.FractionalFee[] memory fractionalFees = new IHederaTokenService.FractionalFee[](1); - fractionalFees[0] = IHederaTokenService.FractionalFee(4, 5, 10, 30, false, treasury); - (int responseCode, address tokenAddress) = HederaTokenService.createFungibleTokenWithCustomFees(token, initialTotalSupply, decimals, fixedFees, fractionalFees); emit ResponseCode(responseCode); @@ -106,12 +135,12 @@ contract TokenCreateCustomContract is HederaTokenService, ExpiryHelper, KeyHelpe function createNonFungibleTokenWithCustomFeesPublic( address treasury, - address fixedFeeTokenAddress, string memory name, string memory symbol, string memory memo, int64 maxSupply, - int64 feeAmount, + IHederaTokenService.FixedFee[] memory fixedFees, + IHederaTokenService.RoyaltyFee[] memory royaltyFees, IHederaTokenService.TokenKey[] memory keys ) public payable { IHederaTokenService.Expiry memory expiry = IHederaTokenService.Expiry( @@ -122,12 +151,6 @@ contract TokenCreateCustomContract is HederaTokenService, ExpiryHelper, KeyHelpe name, symbol, treasury, memo, true, maxSupply, false, keys, expiry ); - IHederaTokenService.FixedFee[] memory fixedFees = new IHederaTokenService.FixedFee[](1); - fixedFees[0] = IHederaTokenService.FixedFee(feeAmount, fixedFeeTokenAddress, false, false, treasury); - - IHederaTokenService.RoyaltyFee[] memory royaltyFees = new IHederaTokenService.RoyaltyFee[](1); - royaltyFees[0] = IHederaTokenService.RoyaltyFee(4, 5, 10, fixedFeeTokenAddress, false, treasury); - (int responseCode, address tokenAddress) = HederaTokenService.createNonFungibleTokenWithCustomFees(token, fixedFees, royaltyFees); @@ -192,4 +215,13 @@ contract TokenCreateCustomContract is HederaTokenService, ExpiryHelper, KeyHelpe revert(); } } + + function approvePublic(address token, address spender, uint256 amount) public returns (int responseCode) { + responseCode = HederaTokenService.approve(token, spender, amount); + emit ResponseCode(responseCode); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert (); + } + } } diff --git a/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol b/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol index 26a54d6ea..d26b8728d 100644 --- a/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol +++ b/contracts/system-contracts/hedera-token-service/examples/token-manage/TokenManagementContract.sol @@ -5,6 +5,7 @@ pragma experimental ABIEncoderV2; import "../../HederaTokenService.sol"; import "../../ExpiryHelper.sol"; import "../../KeyHelper.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; contract TokenManagementContract is HederaTokenService, ExpiryHelper, KeyHelper { @@ -168,4 +169,30 @@ contract TokenManagementContract is HederaTokenService, ExpiryHelper, KeyHelper revert(); } } + + function updateFungibleTokenCustomFeesPublic( + address token, + IHederaTokenService.FixedFee[] memory fixedFees, + IHederaTokenService.FractionalFee[] memory fractionalFees + ) public returns (int responseCode) { + responseCode = HederaTokenService.updateFungibleTokenCustomFees(token, fixedFees, fractionalFees); + emit ResponseCode(responseCode); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert(Strings.toString(uint(responseCode))); + } + } + + function updateNonFungibleTokenCustomFeesPublic( + address token, + IHederaTokenService.FixedFee[] memory fixedFees, + IHederaTokenService.RoyaltyFee[] memory royaltyFees + ) public returns (int responseCode) { + responseCode = HederaTokenService.updateNonFungibleTokenCustomFees(token, fixedFees, royaltyFees); + emit ResponseCode(responseCode); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert(Strings.toString(uint(responseCode))); + } + } } diff --git a/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol b/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol index 8cfe7a58b..b5fad5e36 100644 --- a/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol +++ b/contracts/system-contracts/hedera-token-service/examples/token-transfer/TokenTransferContract.sol @@ -99,4 +99,22 @@ contract TokenTransferContract is HederaTokenService, ExpiryHelper, KeyHelper { revert (); } } + + function grantTokenKycPublic(address token, address account) external returns (int64 responseCode) { + (responseCode) = HederaTokenService.grantTokenKyc(token, account); + emit ResponseCode(responseCode); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert(); + } + } + + function associateTokenPublic(address account, address token) public returns (int responseCode) { + responseCode = HederaTokenService.associateToken(account, token); + emit ResponseCode(responseCode); + + if (responseCode != HederaResponseCodes.SUCCESS) { + revert (); + } + } } diff --git a/package-lock.json b/package-lock.json index c0b8940d9..bbe9e1538 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "elliptic": "^6.5.7" }, "devDependencies": { - "@hashgraph/hedera-local": "^2.29.4", + "@hashgraph/hedera-local": "^2.30.0", "@hashgraph/sdk": "^2.51.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.7", "@nomicfoundation/hardhat-foundry": "^1.1.2", @@ -606,10 +606,11 @@ } }, "node_modules/@hashgraph/hedera-local": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/@hashgraph/hedera-local/-/hedera-local-2.29.4.tgz", - "integrity": "sha512-na1gjtwAAzYdTnEr0uSaMjqNbGM2EpT3ronTeeX1kRHP/7VTBzJkWvvDaZBdByalMoLq2O/bXBguV6bG4PCAUg==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/@hashgraph/hedera-local/-/hedera-local-2.30.0.tgz", + "integrity": "sha512-wKvd5pm038PiVHNSerTMrr0bVkFqSaWlasTlySjcyyk3sNdB8rLw3PxCAl227z2pVbApjI+z6AgWfQXo4dlklQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@hashgraph/sdk": "^2.49.2", "blessed": "^0.1.81", @@ -7850,9 +7851,9 @@ } }, "@hashgraph/hedera-local": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/@hashgraph/hedera-local/-/hedera-local-2.29.4.tgz", - "integrity": "sha512-na1gjtwAAzYdTnEr0uSaMjqNbGM2EpT3ronTeeX1kRHP/7VTBzJkWvvDaZBdByalMoLq2O/bXBguV6bG4PCAUg==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/@hashgraph/hedera-local/-/hedera-local-2.30.0.tgz", + "integrity": "sha512-wKvd5pm038PiVHNSerTMrr0bVkFqSaWlasTlySjcyyk3sNdB8rLw3PxCAl227z2pVbApjI+z6AgWfQXo4dlklQ==", "dev": true, "requires": { "@hashgraph/sdk": "^2.49.2", diff --git a/package.json b/package.json index eebbfd359..fad1ec1aa 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "freeze-network-node": "hardhat run scripts/freeze-network-node.js" }, "devDependencies": { - "@hashgraph/hedera-local": "^2.29.4", + "@hashgraph/hedera-local": "^2.30.0", "@hashgraph/sdk": "^2.51.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.7", "@nomicfoundation/hardhat-foundry": "^1.1.2", diff --git a/test/hip-583/HIP583.js b/test/hip-583/HIP583.js index 7cc0d9e1a..c9af06ee9 100644 --- a/test/hip-583/HIP583.js +++ b/test/hip-583/HIP583.js @@ -66,6 +66,10 @@ describe('HIP583 Test Suite', function () { ], true, true, + false, + true, + true, + true, false ); nftTokenAddress = @@ -83,6 +87,10 @@ describe('HIP583 Test Suite', function () { ], true, true, + false, + true, + true, + true, false ); await utils.associateToken( diff --git a/test/precompile/hedera-token-service/erc-20/ERC20Contract.js b/test/precompile/hedera-token-service/erc-20/ERC20Contract.js index 2b8303aa9..6a924acac 100644 --- a/test/precompile/hedera-token-service/erc-20/ERC20Contract.js +++ b/test/precompile/hedera-token-service/erc-20/ERC20Contract.js @@ -29,7 +29,7 @@ describe('ERC20Contract Test Suite', function () { let tokenAddress; let erc20Contract; let signers; - const TOTAL_SUPPLY = 1000; + const TOTAL_SUPPLY = 10000000000; before(async function () { signers = await ethers.getSigners(); @@ -69,7 +69,7 @@ describe('ERC20Contract Test Suite', function () { it('should be able to get token decimals', async function () { const decimals = await erc20Contract.decimals(tokenAddress); - expect(decimals).to.equal(8); + expect(decimals).to.equal(0); }); it('should be able to get token totalSupply', async function () { diff --git a/test/precompile/hedera-token-service/erc-20/IERC20.js b/test/precompile/hedera-token-service/erc-20/IERC20.js index 24407f814..4de0f8839 100644 --- a/test/precompile/hedera-token-service/erc-20/IERC20.js +++ b/test/precompile/hedera-token-service/erc-20/IERC20.js @@ -33,7 +33,7 @@ describe('IERC20 Test Suite', function () { let tokenAddress; let IERC20; let signers; - const TOTAL_SUPPLY = BigInt(1000); + const TOTAL_SUPPLY = BigInt(10000000000); const AMOUNT = BigInt(33); before(async function () { @@ -76,7 +76,7 @@ describe('IERC20 Test Suite', function () { it('should be able to get token decimals', async function () { const decimals = await IERC20.decimals(); - expect(decimals).to.equal(8); + expect(decimals).to.equal(0); }); it('should be able to get token totalSupply', async function () { diff --git a/test/precompile/hedera-token-service/token-create/tokenCreateContract.js b/test/precompile/hedera-token-service/token-create/tokenCreateContract.js index af7b2bc3b..111f27928 100644 --- a/test/precompile/hedera-token-service/token-create/tokenCreateContract.js +++ b/test/precompile/hedera-token-service/token-create/tokenCreateContract.js @@ -182,7 +182,7 @@ describe('TokenCreateContract Test Suite', function () { const tokenAddressTx = await tokenCreateContract.createFungibleTokenPublic( await tokenCreateContract.getAddress(), { - value: BigInt('10000000000000000000'), + value: BigInt('30000000000000000000'), gasLimit: 1_000_000, } ); @@ -296,7 +296,7 @@ describe('TokenCreateContract Test Suite', function () { const tokenSymbol = 'tokenSymbol'; const tokenMemo = 'memo'; const initialSupply = 1000; - const maxSupply = 10000; + const maxSupply = 20000000000; const decimals = 8; const freezeDefaultStatus = false; const key = PublicKey.fromBytes(utils.getSignerCompressedPublicKey()); @@ -348,7 +348,7 @@ describe('TokenCreateContract Test Suite', function () { signers[0].address, utils.getSignerCompressedPublicKey(), { - value: '10000000000000000000', + value: '30000000000000000000', gasLimit: 1_000_000, } ); diff --git a/test/precompile/hedera-token-service/token-managment/tokenManagmentContract.js b/test/precompile/hedera-token-service/token-managment/tokenManagmentContract.js index a04924173..3c11e2570 100644 --- a/test/precompile/hedera-token-service/token-managment/tokenManagmentContract.js +++ b/test/precompile/hedera-token-service/token-managment/tokenManagmentContract.js @@ -26,17 +26,32 @@ const { pollForNewERC20Balance } = require('../../../../utils/helpers'); describe('TokenManagmentContract Test Suite', function () { const TX_SUCCESS_CODE = 22; + const CUSTOM_SCHEDULE_ALREADY_HAS_NO_FEES = '244'; + const TOKEN_HAS_NO_FEE_SCHEDULE_KEY = '240'; + const CUSTOM_FEE_MUST_BE_POSITIVE = '239'; + const FRACTION_DIVIDES_BY_ZERO = '230'; + const CUSTOM_FEES_LIST_TOO_LONG = '232'; + const INVALID_CUSTOM_FEE_COLLECTOR = '233'; + const INVALID_TOKEN_ID_IN_CUSTOM_FEES = '234'; + const TOKEN_NOT_ASSOCIATED_TO_FEE_COLLECTOR = '235'; let tokenCreateContract; let tokenQueryContract; let tokenManagmentContract; let tokenTransferContract; + let tokenCreateCustomContract; let erc20Contract; let tokenAddress; let nftTokenAddress; let mintedTokenSerialNumber; let signers; let tokenInfoBefore; + let keys; + let tokenCreateCustomContractAddress; + let tokenCreateContractAddress; + let tokenTransferContractAddress; + let tokenQueryContractAddress; + let tokenManagementContractAddress; before(async function () { signers = await ethers.getSigners(); @@ -44,11 +59,19 @@ describe('TokenManagmentContract Test Suite', function () { tokenQueryContract = await utils.deployTokenQueryContract(); tokenManagmentContract = await utils.deployTokenManagementContract(); tokenTransferContract = await utils.deployTokenTransferContract(); + tokenCreateCustomContract = await utils.deployTokenCreateCustomContract(); + + tokenCreateContractAddress = await tokenCreateContract.getAddress(); + tokenTransferContractAddress = await tokenTransferContract.getAddress(); + tokenQueryContractAddress = await tokenQueryContract.getAddress(); + tokenManagementContractAddress = await tokenManagmentContract.getAddress(); + tokenCreateCustomContractAddress = await tokenCreateCustomContract.getAddress(); await utils.updateAccountKeysViaHapi([ - await tokenCreateContract.getAddress(), - await tokenTransferContract.getAddress(), - await tokenManagmentContract.getAddress(), - await tokenQueryContract.getAddress(), + tokenCreateContractAddress, + tokenTransferContractAddress, + tokenManagementContractAddress, + tokenQueryContractAddress, + tokenCreateCustomContractAddress, ]); erc20Contract = await utils.deployERC20Contract(); tokenAddress = await utils.createFungibleTokenWithSECP256K1AdminKey( @@ -1352,4 +1375,1304 @@ describe('TokenManagmentContract Test Suite', function () { }); }); }); + + describe('Update fees', function () { + let feeToken; + let tokenWithFees; + let tenHbars; + let twentyHbars; + let tokenFeeAmount; + + + + before(async function () { + // The owner of the fee token is the tokenCreateContract + const adminKey = utils.constructIHederaTokenKey( + 'ADMIN', + 'SECP256K1', + utils.getSignerCompressedPublicKey(0) + ); + const kycKey = utils.constructIHederaTokenKey( + 'KYC', + 'CONTRACT_ID', + await tokenCreateCustomContract.getAddress() + ); + const freezeKey = utils.constructIHederaTokenKey( + 'FREEZE', + 'CONTRACT_ID', + await tokenCreateCustomContract.getAddress() + ); + const wipeKey = utils.constructIHederaTokenKey( + 'WIPE', + 'CONTRACT_ID', + await tokenCreateCustomContract.getAddress() + ); + const supplyKey = utils.constructIHederaTokenKey( + 'SUPPLY', + 'CONTRACT_ID', + await tokenCreateCustomContract.getAddress() + ); + const feeKey = utils.constructIHederaTokenKey( + 'FEE', + 'CONTRACT_ID', + await tokenCreateCustomContract.getAddress() + ); + const pauseKey = utils.constructIHederaTokenKey( + 'PAUSE', + 'CONTRACT_ID', + await tokenCreateCustomContract.getAddress() + ); + + keys = [adminKey, kycKey, freezeKey, wipeKey, supplyKey, feeKey, pauseKey]; + }) + + beforeEach(async function () { + tenHbars = 10 * utils.tinybarToHbarCoef; + twentyHbars = 20 * utils.tinybarToHbarCoef; + tokenFeeAmount = 50; + initialSupply = 1000000000; + maxSupply = 2000000000; + decimals = 0; + feeToken = await utils.createFungibleTokenWithPresetKeysPublic( + tokenCreateCustomContract, + "FeeToken", + "FT", + "FeeToken", + 1000000000, + 2000000000, + 0, + false, + tokenCreateCustomContractAddress, + ); + }) + + it('should be able to update fixed fee in HTS token', async function () { + //need to associate the fee collector account of the token that will have fees + await utils.associateAndGrantKyc(tokenCreateCustomContract, feeToken, [signers[0].address]); + + const fixedFee = [{amount: tokenFeeAmount, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFee, + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + + // ------------------ Associate and grantKyc to accounts tranfering tokenWithFees ------------------ + //TODO: error handling + await utils.associateAndGrantKyc(tokenCreateContract, tokenWithFees, [signers[1].address, signers[2].address]); + await utils.associateAndGrantKyc(tokenCreateCustomContract, feeToken, [signers[1].address]); + + const grantKycTx = await tokenCreateCustomContract.grantTokenKycPublic(feeToken, tokenCreateCustomContractAddress); + await grantKycTx.wait(); + + const transferTx = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[0].address, signers[1].address], [-500, 500]); + await transferTx.wait(); + + const approveTx = await tokenCreateCustomContract.approvePublic(feeToken, tokenTransferContract, 1000, Constants.GAS_LIMIT_1_000_000); + await approveTx.wait(); + + const transferFeeTokenToSigner1 = await tokenTransferContract.transferTokensPublic(feeToken, [tokenCreateCustomContractAddress, signers[1].address], [-150, 150], Constants.GAS_LIMIT_1_000_000); + await transferFeeTokenToSigner1.wait(); + + const updatedTokenFeeAmount = tokenFeeAmount + 15; + const updatedFixedFee = [{amount: updatedTokenFeeAmount, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, updatedFixedFee, []) + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + + const balanceBeforeTransferTokenWithFees1 = await utils.getTokenBalance(signers[1].address, tokenWithFees); + const balanceBeforeTransferTokenWithFees2 = await utils.getTokenBalance(signers[2].address, tokenWithFees); + const balanceBeforeTransferFeeToken1 = await utils.getTokenBalance(signers[1].address, feeToken); + + const transferBeforeFeeUpdate = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[1].address, signers[2].address], [-50, 50], Constants.GAS_LIMIT_1_000_000); + await transferBeforeFeeUpdate.wait(); + + const balanceAfterTransferTokenWithFees1 = await utils.getTokenBalance(signers[1].address, tokenWithFees); + const balanceAfterTransferTokenWithFees2 = await utils.getTokenBalance(signers[2].address, tokenWithFees); + const balanceAfterTransferFeeToken1 = await utils.getTokenBalance(signers[1].address, feeToken); + + expect(balanceAfterTransferTokenWithFees1).to.be.equal(balanceBeforeTransferTokenWithFees1 - 50); + expect(balanceAfterTransferTokenWithFees2).to.be.equal(balanceBeforeTransferTokenWithFees2 + 50); + expect(balanceAfterTransferFeeToken1).to.be.equal(balanceBeforeTransferFeeToken1 - updatedTokenFeeAmount); + + + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFees); + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + expect(tokenInfoResponse[5].length).to.be.greaterThan(0); + expect(tokenInfoResponse[5][0][2]).to.equal(false); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + }); + + it('should be able to update fixed fee for HBARs', async function () { + const fixedFee = [{amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, + useCurrentTokenForPayment:false, feeCollector: signers[0].address}]; + const tokenWithFixedHbarFee = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFee, + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFixedHbarFee, [ + tokenManagementContractAddress, + tokenCreateContractAddress + ]); + // ------------------ Associate and grantKyc to accounts transfering tokenWithFixedHbarFee ------------------ + await utils.associateAndGrantKyc(tokenCreateContract, tokenWithFixedHbarFee, [signers[1].address, signers[2].address]); + + const transferFromContract = await tokenTransferContract.transferTokensPublic(tokenWithFixedHbarFee, [signers[0].address, signers[1].address], [-500, 500]); + const transferFromContractReceipt = await transferFromContract.wait(); + + const balanceBeforeTransfer0 = await utils.getHbarBalance(signers[1].address); + const balanceBeforeTransferContract0 = await utils.getHbarBalance(signers[2].address); + + const transferBeforeFeeUpdate = await tokenTransferContract.transferTokensPublic(tokenWithFixedHbarFee, [signers[1].address, signers[2].address], [-50, 50], Constants.GAS_LIMIT_1_000_000); + await transferBeforeFeeUpdate.wait(); + + const balanceAfterTransfer = await utils.getHbarBalance(signers[1].address); + const balanceAfterTransferContract = await utils.getHbarBalance(signers[2].address); + + expect(parseFloat(balanceAfterTransfer)).to.be.equal(parseFloat(balanceBeforeTransfer0) - parseFloat(tenHbars/utils.tinybarToHbarCoef)); + const updatedFixedFee = [{amount: twentyHbars, tokenId: "0x0000000000000000000000000000000000000000", useHbarsForPayment: true, + useCurrentTokenForPayment:false, feeCollector: signers[0].address}] + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFixedHbarFee, updatedFixedFee, []) + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + + const transferAfterFeeUpdate = await tokenTransferContract.transferTokensPublic(tokenWithFixedHbarFee, [signers[1].address, signers[2].address], [-50, 50], Constants.GAS_LIMIT_1_000_000); + await transferAfterFeeUpdate.wait(); + const balanceAfterUpdate = await utils.getHbarBalance(signers[1].address); + const balanceAfterUpdateContract = await utils.getHbarBalance(signers[2].address); + + expect(parseFloat(balanceAfterUpdate)).to.be.equal(parseFloat(balanceAfterTransfer) - parseFloat(twentyHbars/utils.tinybarToHbarCoef)); + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFixedHbarFee); + + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + expect(tokenInfoResponse[5].length).to.be.greaterThan(0); + expect(tokenInfoResponse[5][0][2]).to.equal(true); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + }); + + it('should be able to update fixed fee in the same token', async function () { + const fixedFeeSameToken = [{amount: tokenFeeAmount, tokenId: ethers.ZeroAddress, useHbarsForPayment: false, + useCurrentTokenForPayment: true, feeCollector: signers[3].address}]; + const tokenWithFixedFeeInSameToken = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFeeSameToken, + [], + keys + ); + + await utils.updateTokenKeysViaHapi(tokenWithFixedFeeInSameToken, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + ]); + + await utils.associateAndGrantKyc(tokenCreateContract, tokenWithFixedFeeInSameToken, [signers[1].address]); + + const transferTokenFromTreasury = await tokenTransferContract.transferTokensPublic(tokenWithFixedFeeInSameToken, [signers[0].address, signers[1].address], [-500, 500], Constants.GAS_LIMIT_1_000_000); + await transferTokenFromTreasury.wait(); + + const newFeeTokenAmount = tokenFeeAmount + 100; + const fixedFeeSameTokenUpdated = [{amount: newFeeTokenAmount, tokenId: ethers.ZeroAddress, useHbarsForPayment: false, + useCurrentTokenForPayment: true, feeCollector: signers[3].address}]; + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFixedFeeInSameToken, fixedFeeSameTokenUpdated, []); + await updateFeeTx.wait(); + + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFixedFeeInSameToken); + + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + expect(tokenInfoResponse[5].length).to.be.greaterThan(0); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + }); + + it('should be able to update multiple fixed fees in HTS token', async function () { + const feeToken2 = await utils.createFungibleTokenWithPresetKeysPublic( + tokenCreateCustomContract, + "FeeToken2", + "FT2", + "FeeToken2", + initialSupply, + maxSupply, + decimals, + false, + signers[3].address, + ); + //need to associate the fee collector account of the token that will have fees + // with the fee token, since otherwise the collector won't be able to receive this token + const associateTx = await tokenCreateCustomContract.associateTokenPublic(signers[0].address, feeToken2, Constants.GAS_LIMIT_1_000_000); + await associateTx.wait(); + const associateTx2 = await tokenCreateCustomContract.associateTokenPublic(signers[0].address, feeToken, Constants.GAS_LIMIT_1_000_000); + await associateTx2.wait(); + + const fixedFee = {amount: tokenFeeAmount, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const fixedFee2 = {amount: (tokenFeeAmount+20), tokenId: feeToken2, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + + const tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [fixedFee, fixedFee2], + [], + keys + ); + expect(await utils.getTokenBalance(signers[0].address, tokenWithFees)).to.be.equal(utils.initialSupply); + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + const associateTx3 = await tokenCreateCustomContract.associateTokenPublic(signers[2].address, feeToken2, Constants.GAS_LIMIT_1_000_000); + await associateTx3.wait(); + + const newTokenAmount = tokenFeeAmount + 25; + const updatedFixedFee = {amount: newTokenAmount, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const updatedFixedFee2 = {amount: tokenFeeAmount + 18, tokenId: feeToken2, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[2].address}; + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [updatedFixedFee, updatedFixedFee2], []) + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFees); + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + expect(tokenInfoResponse[5].length).to.be.greaterThan(0); + expect(tokenInfoResponse[5][0][0]).to.equal(BigInt(newTokenAmount)); + expect(tokenInfoResponse[5][0][2]).to.equal(false); + expect(tokenInfoResponse[5][0][3]).to.equal(false); + expect(tokenInfoResponse[5][1][0]).to.equal(BigInt(tokenFeeAmount + 18)); + expect(tokenInfoResponse[5][1][2]).to.equal(false); + expect(tokenInfoResponse[5][1][3]).to.equal(false); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + + //TODO: Add transfer and test if the fee is collected + }); + + it('should be able to update multiple fixed fees in HBARs', async function () { + const thirtyHbars = 30 * utils.tinybarToHbarCoef; + const fixedFee = {amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, + useCurrentTokenForPayment:false, feeCollector: signers[0].address}; + const fixedFee2 = {amount: thirtyHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, + useCurrentTokenForPayment:false, feeCollector: signers[0].address}; + const tokenWithFixedHbarFee = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [fixedFee, fixedFee2], + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFixedHbarFee, [ + tokenManagementContractAddress, + tokenCreateContractAddress + ]); + // ------------------ Associate and grantKyc to accounts transfering tokenWithFixedHbarFee ------------------ + await utils.associateAndGrantKyc(tokenCreateContract, tokenWithFixedHbarFee, [signers[1].address, signers[2].address]); + + + const transferFromContract = await tokenTransferContract.transferTokensPublic(tokenWithFixedHbarFee, [signers[0].address, signers[1].address], [-500, 500]); + await transferFromContract.wait(); + + const balanceBeforeTransfer0 = await utils.getHbarBalance(signers[1].address); + + const transferBeforeFeeUpdate = await tokenTransferContract.transferTokensPublic(tokenWithFixedHbarFee, [signers[1].address, signers[2].address], [-50, 50], Constants.GAS_LIMIT_1_000_000); + await transferBeforeFeeUpdate.wait(); + + const balanceAfterTransfer = await utils.getHbarBalance(signers[1].address); + + expect(parseFloat(balanceAfterTransfer)).to.be.equal(parseFloat(balanceBeforeTransfer0) - parseFloat((tenHbars + thirtyHbars)/utils.tinybarToHbarCoef)); + const updatedFixedFee = {amount: twentyHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, + useCurrentTokenForPayment:false, feeCollector: signers[0].address}; + const updatedFixedFee2 = {amount: twentyHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment:false, feeCollector: signers[0].address}; + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFixedHbarFee, [updatedFixedFee,updatedFixedFee2], []) + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + + const transferAfterFeeUpdate = await tokenTransferContract.transferTokensPublic(tokenWithFixedHbarFee, [signers[1].address, signers[2].address], [-50, 50], Constants.GAS_LIMIT_1_000_000); + await transferAfterFeeUpdate.wait(); + const balanceAfterUpdate = await utils.getHbarBalance(signers[1].address); + + expect(parseFloat(balanceAfterUpdate)).to.be.equal(parseFloat(balanceAfterTransfer) - parseFloat(twentyHbars * 2/utils.tinybarToHbarCoef)); + + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFixedHbarFee); + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + expect(tokenInfoResponse[5].length).to.be.greaterThan(0); + expect(tokenInfoResponse[5][0][2]).to.equal(true); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + }); + + it('should be able to update fractional fee with net of transfer false in HTS token', async function () { + const fractionalFeeNumerator = 30; + const fractionalFeeDenominator = 100; + const feeToken2 = await utils.createFungibleTokenWithPresetKeysPublic( + tokenCreateCustomContract, + "FeeToken2", + "FT2", + "FeeToken2", + initialSupply, + maxSupply, + decimals, + false, + signers[3].address, + ); + await utils.associateToken(tokenCreateCustomContract, feeToken2, Constants.Contract.TokenCreateContract); + + const fractionalFee = {numerator: fractionalFeeNumerator, denominator: fractionalFeeDenominator, minimumAmount: 0, + maximumAmount: 0, netOfTransfers: false, feeCollector: signers[0].address}; + const fixedFee2 = {amount: (tokenFeeAmount+50), tokenId: feeToken2, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [fixedFee2], + [fractionalFee], + keys + ); + + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + const updatedFractionalFeeNumerator = fractionalFeeNumerator + 5; + const updatedFractionalFee = [{numerator: updatedFractionalFeeNumerator, denominator: fractionalFeeDenominator, minimumAmount: 100, + maximumAmount: 1000, netOfTransfers: false, feeCollector: signers[0].address}]; + + // make a transfer and ensure that the fee is collected + //apparently first you need to associate and then gran token kyc + await utils.associateAndGrantKyc(tokenCreateContract, tokenWithFees, [signers[1].address, signers[2].address]); + const transferTx = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[0].address, signers[1].address], [-500, 500]); + await transferTx.wait(); + + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [], updatedFractionalFee) + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFees); + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + // fractional fee is at position 7 in the tokenInfo array + expect(tokenInfoResponse[6].length).to.be.greaterThan(0); + expect(tokenInfoResponse[6][0][0]).to.equal(BigInt(35)); + expect(tokenInfoResponse[6][0][2]).to.equal(BigInt(100)); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + + const feeCollectorBalanceBeforeTransfer = await utils.getTokenBalance(signers[0].address, tokenWithFees); + const senderBalanceBeforeTransfer = await utils.getTokenBalance(signers[1].address, tokenWithFees); + const feeToBeCharged = Math.floor(400 * updatedFractionalFeeNumerator / fractionalFeeDenominator); + const transferTx1 = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[1].address, signers[2].address], [-400, 400], Constants.GAS_LIMIT_1_000_000); + await transferTx1.wait(); + + //ensure the fee has been updated and collected + expect(await utils.getTokenBalance(signers[0].address, tokenWithFees)).to.be.equal(feeCollectorBalanceBeforeTransfer + feeToBeCharged); + expect(await utils.getTokenBalance(signers[1].address, tokenWithFees)).to.be.equal(senderBalanceBeforeTransfer - 400); + expect(await utils.getTokenBalance(signers[2].address, tokenWithFees)).to.be.equal(400 - feeToBeCharged); + }); + + it('should be able to update fractional fee with net of transfer true in HTS token', async function () { + const fractionalFeeNumerator = 30; + const fractionalFeeDenominator = 100; + const feeToken2 = await utils.createFungibleTokenWithPresetKeysPublic( + tokenCreateCustomContract, + "FeeToken2", + "FT2", + "FeeToken2", + initialSupply, + maxSupply, + decimals, + false, + signers[3].address, + ); + await utils.associateToken(tokenCreateCustomContract, feeToken2, Constants.Contract.TokenCreateContract); + + const fractionalFee = {numerator: fractionalFeeNumerator, denominator: fractionalFeeDenominator, minimumAmount: 0, + maximumAmount: 0, netOfTransfers: false, feeCollector: signers[0].address}; + const fixedFee2 = {amount: (tokenFeeAmount+50), tokenId: feeToken2, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [fixedFee2], + [fractionalFee], + keys + ); + + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + const updatedFractionalFeeNumerator = fractionalFeeNumerator + 5; + const updatedFractionalFee = [{numerator: updatedFractionalFeeNumerator, denominator: fractionalFeeDenominator, minimumAmount: 100, + maximumAmount: 1000, netOfTransfers: true, feeCollector: signers[0].address}]; + + // make a transfer and ensure that the fee is collected + //apparently first you need to associate and then gran token kyc + + await utils.associateAndGrantKyc(tokenCreateContract, tokenWithFees, [signers[1].address, signers[2].address]); + + const transferTx = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[0].address, signers[1].address], [-1000, 1000]); + await transferTx.wait(); + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [], updatedFractionalFee) + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFees); + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + // fractional fee is at position 7 in the tokenInfo array + expect(tokenInfoResponse[6].length).to.be.greaterThan(0); + expect(tokenInfoResponse[6][0][0]).to.equal(BigInt(35)); + expect(tokenInfoResponse[6][0][2]).to.equal(BigInt(100)); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + + const feeCollectorBalanceBeforeTransfer = await utils.getTokenBalance(signers[0].address, tokenWithFees); + const senderBalanceBeforeTransfer = await utils.getTokenBalance(signers[1].address, tokenWithFees); + const feeToBeCharged = Math.floor(400 * updatedFractionalFeeNumerator / fractionalFeeDenominator); + const transferTx1 = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[1].address, signers[2].address], [-400, 400], Constants.GAS_LIMIT_1_000_000); + await transferTx1.wait(); + + //ensure the fee has been updated and collected + expect(await utils.getTokenBalance(signers[0].address, tokenWithFees)).to.be.equal(feeCollectorBalanceBeforeTransfer + feeToBeCharged); + expect(await utils.getTokenBalance(signers[1].address, tokenWithFees)).to.be.equal(senderBalanceBeforeTransfer - 400 - feeToBeCharged); + expect(await utils.getTokenBalance(signers[2].address, tokenWithFees)).to.be.equal(400); + }); + + it('should be able to update multiple fractional fees in HTS token', async function () { + const fractionalFeeNumerator = 30; + const fractionalFeeDenominator = 100; + const fractionalFeeNumerator2 = 10; + console.log("Creating token") + const feeToken2 = await utils.createFungibleTokenWithPresetKeysPublic( + tokenCreateCustomContract, + "FeeToken2", + "FT2", + "FeeToken2", + initialSupply, + maxSupply, + decimals, + false, + signers[3].address, + ); + await utils.associateToken(tokenCreateCustomContract, feeToken2, Constants.Contract.TokenCreateCustomContract); + + const fixedFeeAmount = tokenFeeAmount + 50; + const fractionalFee = {numerator: fractionalFeeNumerator, denominator: fractionalFeeDenominator, minimumAmount: 0, + maximumAmount: 0, netOfTransfers: false, feeCollector: signers[0].address}; + const fractionalFee2 = {numerator: fractionalFeeNumerator2, denominator: fractionalFeeDenominator, minimumAmount: 0, + maximumAmount: 0, netOfTransfers: false, feeCollector: signers[0].address}; + const fixedFee2 = {amount: fixedFeeAmount, tokenId: feeToken2, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [fixedFee2], + [fractionalFee, fractionalFee2], + keys + ); + + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + const updatedFractionalFeeNumerator = fractionalFeeNumerator + 5; + const updatedFractionalFeeNumerator2 = fractionalFeeNumerator2 - 5; + const updatedFractionalFee = [{numerator: updatedFractionalFeeNumerator, denominator: fractionalFeeDenominator, minimumAmount: 100, + maximumAmount: 1000, netOfTransfers: false, feeCollector: signers[0].address}, + {numerator: updatedFractionalFeeNumerator2, denominator: fractionalFeeDenominator, minimumAmount: 1, + maximumAmount: 1000, netOfTransfers: false, feeCollector: signers[0].address}]; + + // make a transfer and ensure that the fee is collected + //apparently first you need to associate and then gran token kyc + await utils.associateAndGrantKyc(tokenCreateCustomContract, tokenWithFees, [signers[1].address, signers[2].address]); + const transferTx = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[0].address, signers[1].address], [-500, 500]); + await transferTx.wait(); + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [], updatedFractionalFee) + const updateFeeResponseCode = ( + await updateFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + const tokenInfoTx = await tokenQueryContract.getTokenInfoPublic(tokenWithFees); + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.TokenInfo)[0] + .args.tokenInfo; + + // fractional fee is at position 7 in the tokenInfo array + expect(tokenInfoResponse[6].length).to.be.greaterThan(0); + expect(tokenInfoResponse[6][0][0]).to.equal(BigInt(35)); + expect(tokenInfoResponse[6][0][2]).to.equal(BigInt(100)); + expect(tokenInfoResponse[6][1][0]).to.equal(BigInt(5)); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + + const feeCollectorBalanceBeforeTransfer = await utils.getTokenBalance(signers[0].address, tokenWithFees); + const senderBalanceBeforeTransfer = await utils.getTokenBalance(signers[1].address, tokenWithFees); + const feeToBeCharged = Math.floor(400 * ((updatedFractionalFeeNumerator + updatedFractionalFeeNumerator2) / fractionalFeeDenominator)); + + const transferTx1 = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[1].address, signers[2].address], [-400, 400], Constants.GAS_LIMIT_1_000_000); + const transferTx1Receipt = await transferTx1.wait(); + console.log(transferTx1Receipt); + const signer2BalanceAfterTransfer = await utils.getTokenBalance(signers[2].address, tokenWithFees); + + //ensure the fee has been updated and collected + expect(await utils.getTokenBalance(signers[0].address, tokenWithFees)).to.be.equal(feeCollectorBalanceBeforeTransfer + feeToBeCharged); + expect(await utils.getTokenBalance(signers[1].address, tokenWithFees)).to.be.equal(senderBalanceBeforeTransfer - 400); + expect(signer2BalanceAfterTransfer).to.be.equal(400 - feeToBeCharged); + }); + + it('should be able to update royalty fee in HBARs for NFT', async function () { + const fixedFees = []; + const royaltyFees = [{numerator: 10, denominator: 100, amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, feeCollector: signers[2].address}]; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFees, + royaltyFees, + keys + ); + const nftTx = await utils.mintNFT(tokenCreateCustomContract ,nft); + + await utils.associateAndGrantKyc(tokenCreateCustomContract, nft, [signers[1].address, signers[3].address]); + + const transferNft = await tokenTransferContract.transferNFTPublic(nft, signers[0].address, signers[1].address, nftTx); + await transferNft.wait(); + + + await utils.updateTokenKeysViaHapi(nft, [tokenManagementContractAddress, tokenCreateCustomContractAddress]); + const updatedRoyaltyFee = [{numerator: 10, denominator: 100, amount: twentyHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, feeCollector: signers[2].address}]; + const updateRoyaltyFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, [], updatedRoyaltyFee); + await updateRoyaltyFeeTx.wait(); + + const beforeNftTransferHbars2 = await utils.getHbarBalance(signers[2].address); + const beforeNftTransferHbars3 = await utils.getHbarBalance(signers[3].address); + + const transferNftToSigner3 = await tokenTransferContract.transferNFTPublic(nft, signers[1].address, signers[3].address, nftTx); + await transferNftToSigner3.wait(); + + expect(await utils.getTokenBalance(signers[3].address, nft)).to.equal(1); + expect(parseFloat(await utils.getHbarBalance(signers[2].address))).to.equal(beforeNftTransferHbars2 + parseFloat(twentyHbars/utils.tinybarToHbarCoef)); + expect(parseFloat(await utils.getHbarBalance(signers[3].address))).to.equal(beforeNftTransferHbars3 - parseFloat(twentyHbars/utils.tinybarToHbarCoef)); + }); + + it('should be able to update multiple royalty fees in HBARs for NFT', async function () { + const fixedFees = []; + const royaltyFees = [{numerator: 10, denominator: 100, amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, feeCollector: signers[2].address},]; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFees, + royaltyFees, + keys + ); + const nftTx = await utils.mintNFT(tokenCreateCustomContract ,nft); + + await utils.associateAndGrantKyc(tokenCreateCustomContract, nft, [signers[1].address, signers[3].address]); + + const transferNft = await tokenTransferContract.transferNFTPublic(nft, signers[0].address, signers[1].address, nftTx); + await transferNft.wait(); + + + await utils.updateTokenKeysViaHapi(nft, [tokenManagementContractAddress, tokenCreateCustomContractAddress]); + const updatedRoyaltyFee = [{numerator: 10, denominator: 100, amount: twentyHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, feeCollector: signers[2].address}, + {numerator: 10, denominator: 100, amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, feeCollector: signers[2].address}]; + const updateRoyaltyFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, [], updatedRoyaltyFee); + await updateRoyaltyFeeTx.wait(); + console.log("NFT", nft); + const beforeNftTransferHbars2 = await utils.getHbarBalance(signers[2].address); + const beforeNftTransferHbars3 = await utils.getHbarBalance(signers[3].address); + + const transferNftToSigner3 = await tokenTransferContract.transferNFTPublic(nft, signers[1].address, signers[3].address, nftTx); + await transferNftToSigner3.wait(); + + expect(await utils.getTokenBalance(signers[3].address, nft)).to.equal(1); + expect(parseFloat(await utils.getHbarBalance(signers[2].address))).to.equal(beforeNftTransferHbars2 + parseFloat((twentyHbars+tenHbars)/utils.tinybarToHbarCoef)); + expect(parseFloat(await utils.getHbarBalance(signers[3].address))).to.equal(beforeNftTransferHbars3 - parseFloat((twentyHbars+tenHbars)/utils.tinybarToHbarCoef)); + }); + + it('should be able to update fixed fee in HBARs for NFT', async function () { + const fixedFees = [{amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, + useCurrentTokenForPayment: false, feeCollector: signers[2].address}]; + const royaltyFees = []; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFees, + royaltyFees, + keys + ); + const nftTx = await utils.mintNFT(tokenCreateCustomContract ,nft); + + await utils.associateAndGrantKyc(tokenCreateCustomContract, nft, [signers[1].address, signers[3].address]); + + const transferNft = await tokenTransferContract.transferNFTPublic(nft, signers[0].address, signers[1].address, nftTx); + await transferNft.wait(); + + await utils.updateTokenKeysViaHapi(nft, [tokenManagementContractAddress, tokenCreateCustomContractAddress]); + const updatedfixedFees = [{amount: twentyHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, + useCurrentTokenForPayment: false, feeCollector: signers[2].address}]; + const updateRoyaltyFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, updatedfixedFees, []); + await updateRoyaltyFeeTx.wait(); + + const beforeNftTransferHbars2 = await utils.getHbarBalance(signers[2].address); + const beforeNftTransferHbars1 = await utils.getHbarBalance(signers[1].address); + + const transferNftToSigner3 = await tokenTransferContract.transferNFTPublic(nft, signers[1].address, signers[3].address, nftTx); + await transferNftToSigner3.wait(); + + expect(await utils.getTokenBalance(signers[3].address, nft)).to.equal(1); + expect(parseFloat(await utils.getHbarBalance(signers[2].address))).to.equal(beforeNftTransferHbars2 + parseFloat(twentyHbars/utils.tinybarToHbarCoef)); + expect(parseFloat(await utils.getHbarBalance(signers[1].address))).to.equal(beforeNftTransferHbars1 - parseFloat(twentyHbars/utils.tinybarToHbarCoef)); + }); + + it('should be able to update fixed HTS fee for NFT', async function () { + await utils.associateToken(tokenCreateCustomContract, feeToken, Constants.Contract.TokenCreateCustomContract); + //we need to grant kyc and associate token with the fee collector, which is signer[0] + const grantKycFeeCollectorFeeToken = await tokenCreateCustomContract.grantTokenKycPublic(feeToken, signers[0].address); + await grantKycFeeCollectorFeeToken.wait(); + + const fixedFees = [{amount: tokenFeeAmount, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + const royaltyFees = []; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFees, + royaltyFees, + keys + ); + const nftTx = await utils.mintNFT(tokenCreateCustomContract, nft); + + await utils.associateAndGrantKyc(tokenCreateCustomContract, nft, [signers[1].address, signers[3].address]); + const transferNft = await tokenTransferContract.transferNFTPublic(nft, signers[0].address, signers[1].address, nftTx); + await transferNft.wait(); + + + await utils.updateTokenKeysViaHapi(nft, [tokenManagementContractAddress, tokenCreateCustomContractAddress]); + const updatedfixedFees = [{amount: tokenFeeAmount + 13, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + + const updateRoyaltyFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, updatedfixedFees, []); + await updateRoyaltyFeeTx.wait(); + + const beforeNftTransferHbars2 = await utils.getHbarBalance(signers[2].address); + const beforeNftTransferHbars1 = await utils.getHbarBalance(signers[1].address); + + // need to grant kyc from the account which is the kyc key a.k.a tokenCreateCustomContract + //should work witho another contract if token keys are updated + const grantKycSigner1FeeToken = await tokenCreateCustomContract.grantTokenKycPublic(feeToken, signers[1].address); + const grantKycSigner1FeeTokenReceipt = await grantKycSigner1FeeToken.wait(); + + + // ---------- send fee token to signer 1 ------------ + + //prerequisite: signer 1 has to be associated + // approve the tokenTransfer to spend feeTokens + const approveTx = await tokenCreateCustomContract.approvePublic(feeToken, tokenTransferContract, 1000, Constants.GAS_LIMIT_1_000_000); + await approveTx.wait(); + const transferFeeToken = await tokenTransferContract.transferTokensPublic(feeToken, [tokenCreateCustomContractAddress, signers[1].address], [-500, 500]); + await transferFeeToken.wait(); + + const balanceBeforeFeeCollector = await utils.getTokenBalance(signers[0].address, feeToken); + const balanceBeforeSigner1 = await utils.getTokenBalance(signers[1].address, feeToken); + const transferNftToSigner3 = await tokenTransferContract.transferNFTPublic(nft, signers[1].address, signers[3].address, nftTx); + await transferNftToSigner3.wait(); + + expect(await utils.getTokenBalance(signers[1].address, feeToken)).to.equal(balanceBeforeSigner1 - (tokenFeeAmount + 13)); + expect(await utils.getTokenBalance(signers[0].address, feeToken)).to.equal(balanceBeforeFeeCollector + (tokenFeeAmount + 13)); + expect(await utils.getTokenBalance(signers[3].address, nft)).to.equal(1); + }) + + it('should be able to update fixed HTS fee and royalty fee in NFT', async function () { + await utils.associateToken(tokenCreateCustomContract, feeToken, Constants.Contract.TokenCreateContract); + //we need to grant kyc and associate token with the fee collector, which is signer[0] + const grantKycFeeCollectorFeeToken = await tokenCreateCustomContract.grantTokenKycPublic(feeToken, signers[0].address); + await grantKycFeeCollectorFeeToken.wait(); + + const fixedFees = [{amount: tokenFeeAmount, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + const royaltyFees = [{numerator: 10, denominator: 100, amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, feeCollector: signers[2].address}]; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + fixedFees, + royaltyFees, + keys + ); + const nftTx = await utils.mintNFT(tokenCreateCustomContract ,nft); + + await utils.associateAndGrantKyc(tokenCreateCustomContract, nft, [signers[1].address, signers[3].address]); + const transferNft = await tokenTransferContract.transferNFTPublic(nft, signers[0].address, signers[1].address, nftTx); + await transferNft.wait(); + + await utils.updateTokenKeysViaHapi(nft, [tokenManagementContractAddress, tokenCreateCustomContractAddress]); + const updatedfixedFees = [{amount: tokenFeeAmount + 13, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + const updatedRoyaltyFee = [{numerator: 10, denominator: 100, amount: twentyHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, feeCollector: signers[2].address}]; + + const updateRoyaltyFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, updatedfixedFees, updatedRoyaltyFee); + await updateRoyaltyFeeTx.wait(); + + const updateFeeResponseCode = ( + await updateRoyaltyFeeTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.ResponseCode)[0] + .args.responseCode; + const tokenInfoTx = await tokenQueryContract.getNonFungibleTokenInfoPublic(nft, nftTx); + const tokenInfoResponse = ( + await tokenInfoTx.wait() + ).logs.filter((e) => e.fragment.name === Constants.Events.NonFungibleTokenInfo)[0] + .args.tokenInfo; + + // fractional fee is at position 7 in the tokenInfo array + expect(tokenInfoResponse[0][5].length).to.be.greaterThan(0); + expect(tokenInfoResponse[0][7].length).to.be.greaterThan(0); + expect(tokenInfoResponse[0][5][0][0]).to.equal(63); + expect(tokenInfoResponse[0][5][0][1]).to.equal(feeToken); + expect(tokenInfoResponse[0][7][0][2]).to.equal(twentyHbars); + expect(tokenInfoResponse[0][7][0][4]).to.equal(true); + expect(updateFeeResponseCode).to.equal(TX_SUCCESS_CODE); + + // need to grant kyc from the account which is the kyc key a.k.a tokenCreateCustomContract + //should work witho another contract if token keys are updated + const grantKycSigner1FeeToken = await tokenCreateCustomContract.grantTokenKycPublic(feeToken, signers[1].address); + const grantKycSigner1FeeTokenReceipt = await grantKycSigner1FeeToken.wait(); + + + // ---------- send fee token to signer 1 ------------ + + //prerequisite: signer 1 has to be associated + // approve the tokenTransfer to spend feeTokens + const approveTx = await tokenCreateCustomContract.approvePublic(feeToken, tokenTransferContract, 1000, Constants.GAS_LIMIT_1_000_000); + await approveTx.wait(); + + const transferFeeToken = await tokenTransferContract.transferTokensPublic(feeToken, [tokenCreateCustomContractAddress, signers[1].address], [-500, 500]); + await transferFeeToken.wait(); + + const balanceBeforeFeeCollector = await utils.getTokenBalance(signers[0].address, feeToken); + const balanceBeforeSigner1 = await utils.getTokenBalance(signers[1].address, feeToken); + const beforeNftTransferHbars2 = await utils.getHbarBalance(signers[2].address); + const beforeNftTransferHbars3 = await utils.getHbarBalance(signers[3].address); + const transferNftToSigner3 = await tokenTransferContract.transferNFTPublic(nft, signers[1].address, signers[3].address, nftTx); + await transferNftToSigner3.wait(); + + expect(await utils.getTokenBalance(signers[1].address, feeToken)).to.equal(balanceBeforeSigner1 - (tokenFeeAmount + 13)); + expect(await utils.getTokenBalance(signers[0].address, feeToken)).to.equal(balanceBeforeFeeCollector + (tokenFeeAmount + 13)); + expect(await utils.getTokenBalance(signers[3].address, nft)).to.equal(1); + expect(parseFloat(await utils.getHbarBalance(signers[2].address))).to.equal(beforeNftTransferHbars2 + parseFloat(twentyHbars/utils.tinybarToHbarCoef)); + expect(parseFloat(await utils.getHbarBalance(signers[3].address))).to.equal(beforeNftTransferHbars3 - parseFloat(twentyHbars/utils.tinybarToHbarCoef)); + }); + + describe('Update fees negative cases', async function () { + it('should fail when updating fungible token non-existing fixed fee', async function() { + let transactionHash; + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(CUSTOM_SCHEDULE_ALREADY_HAS_NO_FEES); + }); + + it('should fail when updating non fungible token non-existing fixed fee', async function() { + let transactionHash; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(nft, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + const updateFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, [], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(CUSTOM_SCHEDULE_ALREADY_HAS_NO_FEES); + }); + + it('should fail when trying to update fees of fungible token with no fee schedule key', async function() { + let transactionHash; + const keysWithoutFeeSchedule = keys.slice(); + keysWithoutFeeSchedule.splice(5, 1); + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keysWithoutFeeSchedule + ); + + await utils.updateTokenKeysViaHapi(tokenWithFees , [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ], setFeeScheduleKey = false); + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(TOKEN_HAS_NO_FEE_SCHEDULE_KEY); + }); + + it('should fail when trying to update fees of non fungible token with no fee schedule key', async function() { + let transactionHash; + const keysWithoutFeeSchedule = keys.slice(); + keysWithoutFeeSchedule.splice(5, 1); + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keysWithoutFeeSchedule + ); + await utils.updateTokenKeysViaHapi(nft, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + const updateFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, [], []); + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(TOKEN_HAS_NO_FEE_SCHEDULE_KEY); + }); + + it('should fail when fee has negative values', async function() { + const negativeHbars = -10 * utils.tinybarToHbarCoef; + const fixedFee = {amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: false, useCurrentTokenForPayment: true, feeCollector: signers[0].address}; + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [fixedFee], + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees , [ + tokenManagementContractAddress + ]); + let transactionHash; + const updatedFixedFee = {amount: negativeHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [updatedFixedFee], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(CUSTOM_FEE_MUST_BE_POSITIVE); + }) + + it('should fail when fee has negative values for non fungible token', async function() { + let transactionHash; + const negativeHbars = -10 * utils.tinybarToHbarCoef; + const fixedFee = {amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + [fixedFee], + [], + keys + ); + await utils.updateTokenKeysViaHapi(nft, [ + tokenManagementContractAddress, + ]); + + const updatedFixedFee = {amount: negativeHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const updateFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, [updatedFixedFee], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(CUSTOM_FEE_MUST_BE_POSITIVE); + }); + + it('should fail when fractional fee has denominator zero', async function() { + let transactionHash; + const fractionalFee = {numerator: 10, denominator: 100, minimumAmount: 0, + maximumAmount: 0, netOfTransfers: false, feeCollector: signers[0].address}; + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [fractionalFee], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees , [ + tokenManagementContractAddress + ]); + const updatedFractionalFee = {numerator: 10, denominator: 0, minimumAmount: 0, + maximumAmount: 0, netOfTransfers: false, feeCollector: signers[0].address}; + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [], [updatedFractionalFee]) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(FRACTION_DIVIDES_BY_ZERO); + }); + + it('should fail when updating fungible token fees to more than 10', async function() { + let transactionHash; + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress + ]); + + const fees = []; + for (let i = 0; i < 11; i++) { + fees.push({amount: tokenFeeAmount + i, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment: false, feeCollector: signers[0].address}); + } + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, fees, []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(CUSTOM_FEES_LIST_TOO_LONG); + }); + + it('should fail when updating NFT token fees to more than 10', async function() { + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(nft, [ + tokenManagementContractAddress, + ]); + + let transactionHash; + const fees = []; + for (let i = 0; i < 11; i++) { + fees.push({amount: tokenFeeAmount + i, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment: false, feeCollector: signers[0].address}); + } + const updateFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, fees, []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(CUSTOM_FEES_LIST_TOO_LONG); + }); + + it('should fail when the provided fee collector is invalid', async function() { + let transactionHash; + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress + ]); + const fixedFee = {amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment: false, feeCollector: feeToken}; + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [fixedFee], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(INVALID_CUSTOM_FEE_COLLECTOR); + }); + + it('should fail when the provided fee collector is invalid for NFT', async function() { + let transactionHash; + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(nft, [ + tokenManagementContractAddress, + ]); + const fixedFee = {amount: tenHbars, tokenId: ethers.ZeroAddress, useHbarsForPayment: true, useCurrentTokenForPayment: false, feeCollector: feeToken}; + const updateFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, [fixedFee], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(INVALID_CUSTOM_FEE_COLLECTOR); + }); + + it('should fail when the provided token id is invalid', async function() { + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress + ]); + + const fixedFee = {amount: 10, tokenId: signers[1].address, useHbarsForPayment: false, useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, [fixedFee], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(INVALID_TOKEN_ID_IN_CUSTOM_FEES); + }); + + it('should fail when the provided token id is invalid for NFT', async function() { + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(nft, [ + tokenManagementContractAddress, + ]); + const fixedFee = {amount: 10, tokenId: signers[1].address, useHbarsForPayment: false, useCurrentTokenForPayment: false, feeCollector: signers[0].address}; + let transactionHash; + const updateFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, [fixedFee], []) + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(INVALID_TOKEN_ID_IN_CUSTOM_FEES); + }); + + it('should fail for updateFungibleTokenCustomFees when token is not associated to fee collector', async function () { + //need to associate the fee collector account of the token that will have fees + tokenWithFees = await utils.createFungibleTokenWithCustomFeesAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + await utils.updateTokenKeysViaHapi(tokenWithFees, [ + tokenManagementContractAddress, + tokenTransferContractAddress, + tokenCreateContractAddress, + tokenCreateCustomContractAddress + ]); + + + // ------------------ Associate and grantKyc to accounts tranfering tokenWithFees ------------------ + //TODO: error handling + await utils.associateAndGrantKyc(tokenCreateContract, tokenWithFees, [signers[1].address, signers[2].address]); + await utils.associateAndGrantKyc(tokenCreateCustomContract, feeToken, [signers[1].address]); + + const grantKycTx = await tokenCreateCustomContract.grantTokenKycPublic(feeToken, tokenCreateCustomContractAddress); + await grantKycTx.wait(); + + const transferTx = await tokenTransferContract.transferTokensPublic(tokenWithFees, [signers[0].address, signers[1].address], [-500, 500]); + await transferTx.wait(); + + const approveTx = await tokenCreateCustomContract.approvePublic(feeToken, tokenTransferContract, 1000, Constants.GAS_LIMIT_1_000_000); + await approveTx.wait(); + + const transferFeeTokenToSigner1 = await tokenTransferContract.transferTokensPublic(feeToken, [tokenCreateCustomContractAddress, signers[1].address], [-150, 150], Constants.GAS_LIMIT_1_000_000); + await transferFeeTokenToSigner1.wait(); + + const updatedTokenFeeAmount = tokenFeeAmount + 15; + const updatedFixedFee = [{amount: updatedTokenFeeAmount, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + + const updateFeeTx = await tokenManagmentContract.updateFungibleTokenCustomFeesPublic(tokenWithFees, updatedFixedFee, []) + let transactionHash; + try { + await updateFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(TOKEN_NOT_ASSOCIATED_TO_FEE_COLLECTOR); + }); + + it('should fail for updateNonFungibleTokenCustomFees when token is not associated to fee collector', async function () { + //we need to grant kyc and associate token with the fee collector, which is signer[0] + const nft = await utils.createNonFungibleTokenWithCustomRoyaltyFeeAndKeys( + tokenCreateCustomContract, + signers[0].address, + [], + [], + keys + ); + const nftTx = await utils.mintNFT(tokenCreateCustomContract, nft); + + await utils.associateAndGrantKyc(tokenCreateCustomContract, nft, [signers[1].address, signers[3].address]); + const transferNft = await tokenTransferContract.transferNFTPublic(nft, signers[0].address, signers[1].address, nftTx); + await transferNft.wait(); + + + await utils.updateTokenKeysViaHapi(nft, [tokenManagementContractAddress, tokenCreateCustomContractAddress]); + const updatedfixedFees = [{amount: tokenFeeAmount + 13, tokenId: feeToken, useHbarsForPayment: false, + useCurrentTokenForPayment: false, feeCollector: signers[0].address}]; + + let transactionHash; + const updateRoyaltyFeeTx = await tokenManagmentContract.updateNonFungibleTokenCustomFeesPublic(nft, updatedfixedFees, []); + try{ + await updateRoyaltyFeeTx.wait(); + } catch (error) { + transactionHash = error.receipt.hash; + } + + const revertReason = await utils.getRevertReasonFromReceipt(transactionHash); + const decodeRevertReason = utils.decodeErrorMessage(revertReason); + expect(decodeRevertReason).to.equal(TOKEN_NOT_ASSOCIATED_TO_FEE_COLLECTOR); + }); + }); + }); }); diff --git a/test/precompile/hedera-token-service/utils.js b/test/precompile/hedera-token-service/utils.js index c89dc0ff3..3624b7a46 100644 --- a/test/precompile/hedera-token-service/utils.js +++ b/test/precompile/hedera-token-service/utils.js @@ -32,6 +32,7 @@ const { TokenId, TokenUpdateTransaction, TokenAssociateTransaction, + AccountBalanceQuery } = require('@hashgraph/sdk'); const Constants = require('../../constants'); @@ -41,6 +42,9 @@ class Utils { static createTokenCustomFeesCost = '60000000000000000000'; static tinybarToWeibarCoef = 10_000_000_000; static tinybarToHbarCoef = 100_000_000; + static initialSupply = 1000000000000; + static maxSupply = 2000000000000; + static nftMaxSupply = 20000; static KeyType = { ADMIN: 1, @@ -206,6 +210,41 @@ class Utils { gasLimit: 1_000_000, }); const tokenAddressReceipt = await tokenAddressTx.wait(); + + const { tokenAddress } = tokenAddressReceipt.logs.filter( + (e) => e.fragment.name === Constants.Events.CreatedToken + )[0].args; + + return tokenAddress; + } + + static async createFungibleTokenWithPresetKeysPublic( + contract, + name, + symbol, + memo, + initialSupply, + maxSupply, + decimals, + freezeDefaultStatus, + treasury, + ) { + const tokenAddressTx = await contract.createFungibleTokenWithPresetKeys( + name, + symbol, + memo, + initialSupply, + maxSupply, + decimals, + freezeDefaultStatus, + treasury, + { + value: BigInt(this.createTokenCost), + gasLimit: 1_000_000, + } + ); + const tokenAddressReceipt = await tokenAddressTx.wait(); + const { tokenAddress } = tokenAddressReceipt.logs.filter( (e) => e.fragment.name === Constants.Events.CreatedToken )[0].args; @@ -335,6 +374,66 @@ class Utils { return tokenAddress; } + // Helper function to associate and grant KYC + static async associateAndGrantKyc(contract, token, addresses) { + for (const address of addresses) { + const associateTx = await contract.associateTokenPublic(address, token); + await associateTx.wait(); // Ensure the association is completed before proceeding + + const grantKycTx = await contract.grantTokenKycPublic(token, address); + await grantKycTx.wait(); // Ensure the KYC grant is completed before proceeding + } +} + + static async createFungibleTokenWithCustomFeesAndKeys(contract, treasury, fixedFees, fractionalFees, keys) { + const updateFeesTx = await contract.createFungibleTokenWithCustomFeesPublic( + treasury, + "Hedera Token Fees", + "HTF", + "Hedera Token With Fees", + this.initialSupply, + this.maxSupply, + 0, + fixedFees, + fractionalFees, + keys, + { + value: BigInt(this.createTokenCost), + gasLimit: 1_000_000, + } + ); + const updateFeesReceipt = await updateFeesTx.wait(); + + const { tokenAddress } = updateFeesReceipt.logs.filter( + (e) => e.fragment.name === Constants.Events.CreatedToken + )[0].args; + + return tokenAddress; + } + + static async createNonFungibleTokenWithCustomRoyaltyFeeAndKeys(contract, treasury, fixedFees, royaltyFees, keys) { + const tokenAddressTx = await contract.createNonFungibleTokenWithCustomFeesPublic( + treasury, + "Non Fungible Token With Custom Fees", + "NFTF", + "Non Fungible Token With Custom Fees", + this.nftMaxSupply, + fixedFees, + royaltyFees, + keys, + { + value: BigInt(this.createTokenCost), + gasLimit: 1_000_000, + } + ); + const tokenAddressReceipt = await tokenAddressTx.wait(); + const { tokenAddress } = tokenAddressReceipt.logs.filter( + (e) => e.fragment.name === Constants.Events.CreatedToken + )[0].args; + + return tokenAddress; + }; + static async createNonFungibleToken(contract, treasury) { const tokenAddressTx = await contract.createNonFungibleTokenPublic( treasury, @@ -395,6 +494,64 @@ class Utils { return tokenAddress; } + static hexToASCII(str) { + const hex = str.toString(); + let ascii = ''; + for (let n = 0; n < hex.length; n += 2) { + ascii += String.fromCharCode(parseInt(hex.substring(n, n + 2), 16)); + } + return ascii; + } + + /** + * Converts an EVM ErrorMessage to a readable form. For example this : + * 0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d53657420746f2072657665727400000000000000000000000000000000000000 + * will be converted to "Set to revert" + * @param message + */ + static decodeErrorMessage (message ) { + const EMPTY_HEX = '0x'; + if (!message) return ''; + + // If the message does not start with 0x, it is not an error message, return it as is + if (!message.includes(EMPTY_HEX)) return message; + + message = message.replace(/^0x/, ''); // Remove the starting 0x + const strLen = parseInt(message.slice(8 + 64, 8 + 128), 16); // Get the length of the readable text + const resultCodeHex = message.slice(8 + 128, 8 + 128 + strLen * 2); // Extract the hex of the text + return this.hexToASCII(resultCodeHex); + }; + + static async getRevertReasonFromReceipt(hash) { + const receipt = await ethers.provider.send("eth_getTransactionReceipt", [ + hash + ]); + + return receipt.revertReason; + } + + static async getHbarBalance(address) { + const balanceJson = (await this.getAccountBalance(address)).toJSON(); + const balanceFloat = parseFloat(balanceJson.hbars); + + return balanceFloat; + } + + static async getTokenBalance(accountAddress, tokenAddress) { + const accountBalanceJson = (await this.getAccountBalance(accountAddress)).toJSON(); + const tokenId = await AccountId.fromEvmAddress(0, 0, tokenAddress).toString(); + const balance = accountBalanceJson.tokens.find((e) => e.tokenId === tokenId); + + return parseInt(balance.balance); + } + + static async updateFungibleTokenCustomFees(contract, token, treasury, feeToken, feeAmount) { + const updateFees = await contract.updateFungibleTokenCustomFeesPublic( + token, treasury, feeToken, feeAmount + ); + const receipt = await updateFees.wait(); + } + static async mintNFT(contract, nftTokenAddress, data = ['0x01']) { const mintNftTx = await contract.mintTokenPublic( nftTokenAddress, @@ -441,6 +598,12 @@ class Utils { signers[1] ); + const associateTx3 = await ethers.getContractAt( + contractName, + await contract.getAddress(), + signers[2] + ); + await contract.associateTokenPublic( await contract.getAddress(), tokenAddress, @@ -456,6 +619,11 @@ class Utils { tokenAddress, Constants.GAS_LIMIT_1_000_000 ); + await associateTx3.associateTokenPublic( + signers[2].address, + tokenAddress, + Constants.GAS_LIMIT_1_000_000 + ); } static async grantTokenKyc(contract, tokenAddress) { @@ -577,6 +745,18 @@ class Utils { } } + static async getAccountBalance(address) { + const client = await Utils.createSDKClient(); + const accountId = await Utils.getAccountId( + address, + client + ); + const tokenBalance = await new AccountBalanceQuery() + .setAccountId(accountId) + .execute(client); + return tokenBalance; + } + static async updateTokenKeysViaHapi( tokenAddress, contractAddresses, @@ -585,7 +765,8 @@ class Utils { setKyc = true, setFreeze = true, setSupply = true, - setWipe = true + setWipe = true, + setFeeSchedule = true ) { const signers = await ethers.getSigners(); const clientGenesis = await Utils.createSDKClient(); @@ -620,6 +801,7 @@ class Utils { if (setFreeze) tx.setFreezeKey(keyList); if (setSupply) tx.setSupplyKey(keyList); if (setWipe) tx.setWipeKey(keyList); + if (setFeeSchedule) tx.setFeeScheduleKey(keyList); await ( await tx.freezeWith(clientSigner0).sign(pkSigners[0])