diff --git a/brightIDfaucet/celery.py b/brightIDfaucet/celery.py index 94bfa6da..bfa25893 100644 --- a/brightIDfaucet/celery.py +++ b/brightIDfaucet/celery.py @@ -38,34 +38,21 @@ "task": "faucet.tasks.update_tokentap_claim_for_verified_lightning_claims", "schedule": 9, }, - 'update-tokens-price': { + "update-tokens-price": { "task": "faucet.tasks.update_tokens_price", "schedule": 600, }, - 'update-donation-receipt-status': { + "update-donation-receipt-status": { "task": "faucet.tasks.update_donation_receipt_pending_status", "schedule": 180, }, - "draw-prizetap-raffles": { - "task": "prizetap.tasks.draw_the_expired_raffles", - "schedule": 300 - }, - "set-raffle-winner": { - "task": "prizetap.tasks.set_the_winner_of_raffles", - "schedule": 300 - }, - "request-random-words-for-linea-raffles": { - "task": "prizetap.tasks.request_random_words_for_expired_linea_raffles", - "schedule": 150 - }, - "draw-linea-raffles": { - "task": "prizetap.tasks.draw_expired_linea_raffles", - "schedule": 60 + "request-random-words-for-raffles": { + "task": "prizetap.tasks.request_random_words_for_expired_raffles", + "schedule": 120, }, - "set-linea-raffle-winners": { - "task": "prizetap.tasks.set_the_winner_of_linea_raffles", - "schedule": 60 - } + "set-raffle-random-words": {"task": "prizetap.tasks.set_raffle_random_words", "schedule": 120}, + "set-raffle-winners": {"task": "prizetap.tasks.set_raffle_winners", "schedule": 300}, + "get-raffle-winners": {"task": "prizetap.tasks.get_raffle_winners", "schedule": 300}, } # Load task modules from all registered Django apps. diff --git a/prizetap/constants.py b/prizetap/constants.py index 840296da..e1cb393a 100644 --- a/prizetap/constants.py +++ b/prizetap/constants.py @@ -1,4501 +1,1643 @@ PRIZETAP_ERC20_ABI = [ - { - "inputs": [ - { - "internalType": "address", - "name": "_chainlinkVRFCoordinator", - "type": "address" - }, - { - "internalType": "uint64", - "name": "_chainlinkVRFSubscriptionId", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "_chainlinkKeyHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_muonAppId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } - ], - "internalType": "struct IMuonClient.PublicKey", - "name": "_muonPublicKey", - "type": "tuple" - }, - { - "internalType": "address", - "name": "_muon", - "type": "address" - }, - { - "internalType": "address", - "name": "_muonValidGateway", - "type": "address" - }, - { - "internalType": "address", - "name": "_admin", - "type": "address" - }, - { - "internalType": "address", - "name": "_operator", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "have", - "type": "address" - }, - { - "internalType": "address", - "name": "want", - "type": "address" - } - ], - "name": "OnlyCoordinatorCanFulfill", - "type": "error" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - } - ], - "name": "Participate", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "winner", - "type": "address" - } - ], - "name": "PrizeClaimed", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "PrizeRefunded", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "RaffleCreated", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "organizer", - "type": "address" - } - ], - "name": "RaffleHeld", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "rejector", - "type": "address" - } - ], - "name": "RaffleRejected", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": False, - "internalType": "uint256[]", - "name": "randomWords", - "type": "uint256[]" - } - ], - "name": "VRFRequestFulfilled", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "VRFRequestSent", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "winner", - "type": "address" - } - ], - "name": "WinnerSpecified", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPERATOR_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "claimPrize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "currency", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxParticipants", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "startTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "requirementsHash", - "type": "bytes32" - } - ], - "name": "createRaffle", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "getParticipants", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "heldRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "isParticipated", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lastRaffleId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muon", - "outputs": [ - { - "internalType": "contract IMuonClient", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muonAppId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muonPublicKey", - "outputs": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muonValidGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } - ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } - ], - "name": "participateInRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "raffles", - "outputs": [ - { - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "prizeAmount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "currency", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxParticipants", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "startTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "participantsCount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "winner", - "type": "address" - }, - { - "internalType": "bool", - "name": "exists", - "type": "bool" - }, - { - "internalType": "enum AbstractPrizetapRaffle.Status", - "name": "status", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "requirementsHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "randomWords", - "type": "uint256[]" - } - ], - "name": "rawFulfillRandomWords", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "refundPrize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "rejectRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "gaslimit", - "type": "uint32" - } - ], - "name": "setCallbackGasLimit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_muonAddress", - "type": "address" - } - ], - "name": "setMuonAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_muonAppId", - "type": "uint256" - } - ], - "name": "setMuonAppId", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_gatewayAddress", - "type": "address" - } - ], - "name": "setMuonGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } - ], - "internalType": "struct IMuonClient.PublicKey", - "name": "_muonPublicKey", - "type": "tuple" - } - ], - "name": "setMuonPublicKey", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "periodSeconds", - "type": "uint256" - } - ], - "name": "setValidationPeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "keyHash", - "type": "bytes32" - } - ], - "name": "setVrfKeyHash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "count", - "type": "uint16" - } - ], - "name": "setVrfRequestConfirmations", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "id", - "type": "uint64" - } - ], - "name": "setVrfSubscriptionId", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "validationPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } - ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "sign", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } - ], - "name": "verifyTSSAndGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "vrfRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -] - -PRIZETAP_ERC721_ABI = [ - { - "inputs": [ - { - "internalType": "address", - "name": "_chainlinkVRFCoordinator", - "type": "address" - }, - { - "internalType": "uint64", - "name": "_chainlinkVRFSubscriptionId", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "_chainlinkKeyHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_muonAppId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } - ], - "internalType": "struct IMuonClient.PublicKey", - "name": "_muonPublicKey", - "type": "tuple" - }, - { - "internalType": "address", - "name": "_muon", - "type": "address" - }, - { - "internalType": "address", - "name": "_muonValidGateway", - "type": "address" - }, - { - "internalType": "address", - "name": "_admin", - "type": "address" - }, - { - "internalType": "address", - "name": "_operator", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "have", - "type": "address" - }, - { - "internalType": "address", - "name": "want", - "type": "address" - } - ], - "name": "OnlyCoordinatorCanFulfill", - "type": "error" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - } - ], - "name": "Participate", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "winner", - "type": "address" - } - ], - "name": "PrizeClaimed", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "PrizeRefunded", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "RaffleCreated", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "organizer", - "type": "address" - } - ], - "name": "RaffleHeld", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "rejector", - "type": "address" - } - ], - "name": "RaffleRejected", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": False, - "internalType": "uint256[]", - "name": "randomWords", - "type": "uint256[]" - } - ], - "name": "VRFRequestFulfilled", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "VRFRequestSent", - "type": "event" - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "winner", - "type": "address" - } - ], - "name": "WinnerSpecified", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPERATOR_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "_ERC721_RECEIVED", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "claimPrize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "collection", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxParticipants", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "startTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "requirementsHash", - "type": "bytes32" - } - ], - "name": "createRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "getParticipants", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "heldRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "isParticipated", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lastRaffleId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muon", - "outputs": [ - { - "internalType": "contract IMuonClient", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muonAppId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muonPublicKey", - "outputs": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "muonValidGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } + { + "inputs": [ + {"internalType": "uint256", "name": "_muonAppId", "type": "uint256"}, + { + "components": [ + {"internalType": "uint256", "name": "x", "type": "uint256"}, + {"internalType": "uint8", "name": "parity", "type": "uint8"}, + ], + "internalType": "struct IMuonClient.PublicKey", + "name": "_muonPublicKey", + "type": "tuple", + }, + {"internalType": "address", "name": "_muon", "type": "address"}, + {"internalType": "address", "name": "_muonValidGateway", "type": "address"}, + {"internalType": "address", "name": "_admin", "type": "address"}, + {"internalType": "address", "name": "_operator", "type": "address"}, ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } - ], - "name": "participateInRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "pause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "raffles", - "outputs": [ - { - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "internalType": "address", - "name": "collection", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxParticipants", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "startTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "participantsCount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "winner", - "type": "address" - }, - { - "internalType": "bool", - "name": "exists", - "type": "bool" - }, - { - "internalType": "enum AbstractPrizetapRaffle.Status", - "name": "status", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "requirementsHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "randomWords", - "type": "uint256[]" - } - ], - "name": "rawFulfillRandomWords", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "refundPrize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "rejectRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "gaslimit", - "type": "uint32" - } - ], - "name": "setCallbackGasLimit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_muonAddress", - "type": "address" - } - ], - "name": "setMuonAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_muonAppId", - "type": "uint256" - } - ], - "name": "setMuonAppId", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_gatewayAddress", - "type": "address" - } - ], - "name": "setMuonGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": False, + "inputs": [ + {"indexed": True, "internalType": "address", "name": "user", "type": "address"}, + {"indexed": False, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": False, "internalType": "uint256", "name": "multiplier", "type": "uint256"}, ], - "internalType": "struct IMuonClient.PublicKey", - "name": "_muonPublicKey", - "type": "tuple" - } - ], - "name": "setMuonPublicKey", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "periodSeconds", - "type": "uint256" - } - ], - "name": "setValidationPeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "keyHash", - "type": "bytes32" - } - ], - "name": "setVrfKeyHash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "count", - "type": "uint16" - } - ], - "name": "setVrfRequestConfirmations", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "id", - "type": "uint64" - } - ], - "name": "setVrfSubscriptionId", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "validationPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } + "name": "Participate", + "type": "event", + }, + { + "anonymous": False, + "inputs": [{"indexed": False, "internalType": "address", "name": "account", "type": "address"}], + "name": "Paused", + "type": "event", + }, + { + "anonymous": False, + "inputs": [ + {"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": True, "internalType": "address", "name": "winner", "type": "address"}, ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "sign", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } - ], - "name": "verifyTSSAndGateway", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "vrfRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -] - -UNITAP_PASS_ABI = [ + "name": "PrizeClaimed", + "type": "event", + }, { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" + "anonymous": False, + "inputs": [{"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "PrizeRefunded", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": True, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } + {"indexed": True, "internalType": "address", "name": "initiator", "type": "address"}, + {"indexed": False, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, ], - "name": "Approval", - "type": "event" + "name": "RaffleCreated", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": False, - "internalType": "bool", - "name": "approved", - "type": "bool" - } + {"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": True, "internalType": "address", "name": "rejector", "type": "address"}, ], - "name": "ApprovalForAll", - "type": "event" + "name": "RaffleRejected", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "previousAdminRole", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "newAdminRole", "type": "bytes32"}, ], "name": "RoleAdminChanged", - "type": "event" + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], "name": "RoleGranted", - "type": "event" + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], "name": "RoleRevoked", - "type": "event" + "type": "event", }, { "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "name": "SetBaseURI", - "type": "event" + "inputs": [{"indexed": False, "internalType": "address", "name": "account", "type": "address"}], + "name": "Unpaused", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": True, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } + {"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": False, "internalType": "uint256", "name": "fromId", "type": "uint256"}, + {"indexed": False, "internalType": "uint256", "name": "toId", "type": "uint256"}, ], - "name": "Transfer", - "type": "event" + "name": "WinnersSpecified", + "type": "event", }, { "inputs": [], "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "MINTER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "name": "MAX_NUM_WINNERS", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", + "inputs": [], + "name": "OPERATOR_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "claimPrize", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } + {"internalType": "uint256", "name": "amount", "type": "uint256"}, + {"internalType": "address", "name": "currency", "type": "address"}, + {"internalType": "uint256", "name": "maxParticipants", "type": "uint256"}, + {"internalType": "uint256", "name": "maxMultiplier", "type": "uint256"}, + {"internalType": "uint256", "name": "startTime", "type": "uint256"}, + {"internalType": "uint256", "name": "endTime", "type": "uint256"}, + {"internalType": "uint256", "name": "winnersCount", "type": "uint256"}, + {"internalType": "bytes32", "name": "requirementsHash", "type": "bytes32"}, ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + "name": "createRaffle", + "outputs": [], + "stateMutability": "payable", + "type": "function", + }, + { + "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "fromId", "type": "uint256"}, + {"internalType": "uint256", "name": "toId", "type": "uint256"}, ], + "name": "getParticipants", + "outputs": [{"internalType": "address[]", "name": "participants", "type": "address[]"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}], + "name": "getRoleAdmin", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "fromId", "type": "uint256"}, + {"internalType": "uint256", "name": "toId", "type": "uint256"}, ], + "name": "getWinners", + "outputs": [{"internalType": "address[]", "name": "winners", "type": "address[]"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "getWinnersCount", + "outputs": [{"internalType": "uint256", "name": "winnersCount", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], "name": "grantRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + {"internalType": "address", "name": "", "type": "address"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], + "name": "isParticipated", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "address", "name": "", "type": "address"}, ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + "name": "isWinner", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "address", "name": "", "type": "address"}, ], + "name": "isWinnerClaimed", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "name", + "name": "lastRaffleId", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "muon", + "outputs": [{"internalType": "contract IMuonClient", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "muonAppId", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "muonPublicKey", "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } + {"internalType": "uint256", "name": "x", "type": "uint256"}, + {"internalType": "uint8", "name": "parity", "type": "uint8"}, ], "stateMutability": "view", - "type": "function" + "type": "function", + }, + { + "inputs": [], + "name": "muonValidGateway", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "address", "name": "", "type": "address"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], + "name": "participantPositions", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "multiplier", "type": "uint256"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "signature", + "type": "tuple", }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "name": "renounceRole", + "name": "participateInRaffle", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", + }, + {"inputs": [], "name": "pause", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, + { + "inputs": [], + "name": "paused", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "raffleParticipants", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], - "name": "safeMint", + "name": "raffleWinners", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "name": "raffles", + "outputs": [ + {"internalType": "address", "name": "initiator", "type": "address"}, + {"internalType": "uint256", "name": "prizeAmount", "type": "uint256"}, + {"internalType": "address", "name": "currency", "type": "address"}, + {"internalType": "uint256", "name": "maxParticipants", "type": "uint256"}, + {"internalType": "uint256", "name": "maxMultiplier", "type": "uint256"}, + {"internalType": "uint256", "name": "startTime", "type": "uint256"}, + {"internalType": "uint256", "name": "endTime", "type": "uint256"}, + {"internalType": "uint256", "name": "lastParticipantIndex", "type": "uint256"}, + {"internalType": "uint256", "name": "lastWinnerIndex", "type": "uint256"}, + {"internalType": "uint256", "name": "participantsCount", "type": "uint256"}, + {"internalType": "uint256", "name": "winnersCount", "type": "uint256"}, + {"internalType": "bool", "name": "exists", "type": "bool"}, + {"internalType": "enum AbstractPrizetapRaffle.Status", "name": "status", "type": "uint8"}, + {"internalType": "bytes32", "name": "requirementsHash", "type": "bytes32"}, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "refundPrize", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "refundRemainingPrizes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "rejectRaffle", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "name": "safeTransferFrom", + "name": "renounceRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "name": "setApprovalForAll", + "name": "revokeRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", + }, + { + "inputs": [{"internalType": "address", "name": "_muonAddress", "type": "address"}], + "name": "setMuonAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "_muonAppId", "type": "uint256"}], + "name": "setMuonAppId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "address", "name": "_gatewayAddress", "type": "address"}], + "name": "setMuonGateway", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { "inputs": [ { - "internalType": "string", - "name": "baseURI_", - "type": "string" + "components": [ + {"internalType": "uint256", "name": "x", "type": "uint256"}, + {"internalType": "uint8", "name": "parity", "type": "uint8"}, + ], + "internalType": "struct IMuonClient.PublicKey", + "name": "_muonPublicKey", + "type": "tuple", } ], - "name": "setBaseURI", + "name": "setMuonPublicKey", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "expirationTime", "type": "uint256"}, + {"internalType": "uint256[]", "name": "randomNumbers", "type": "uint256[]"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "signature", + "type": "tuple", + }, + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "stateMutability": "view", - "type": "function" + "name": "setRaffleRandomNumbers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } + "inputs": [{"internalType": "uint256", "name": "periodSeconds", "type": "uint256"}], + "name": "setValidationPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "toId", "type": "uint256"}, ], + "name": "setWinners", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], + "name": "supportsInterface", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, + {"inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, { "inputs": [], - "name": "tokenIdCounter", - "outputs": [ - { - "internalType": "uint256", - "name": "idCounter", - "type": "uint256" - } - ], + "name": "validationPeriod", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "multiplier", "type": "uint256"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "sign", + "type": "tuple", + }, + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "stateMutability": "view", - "type": "function" + "name": "verifyParticipationSig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { "inputs": [ + {"internalType": "uint256", "name": "expirationTime", "type": "uint256"}, + {"internalType": "uint256[]", "name": "randomNumbers", "type": "uint256[]"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "sign", + "type": "tuple", }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "name": "transferFrom", + "name": "verifyRandomNumberSig", "outputs": [], "stateMutability": "nonpayable", - "type": "function" - } + "type": "function", + }, ] -VRF_CLIENT_ABI = [ +PRIZETAP_ERC721_ABI = [ { "inputs": [ + {"internalType": "uint256", "name": "_muonAppId", "type": "uint256"}, { - "internalType": "address", - "name": "_chainlinkVRFCoordinator", - "type": "address" - }, - { - "internalType": "uint64", - "name": "_chainlinkVRFSubscriptionId", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "_chainlinkKeyHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_admin", - "type": "address" + "components": [ + {"internalType": "uint256", "name": "x", "type": "uint256"}, + {"internalType": "uint8", "name": "parity", "type": "uint8"}, + ], + "internalType": "struct IMuonClient.PublicKey", + "name": "_muonPublicKey", + "type": "tuple", }, - { - "internalType": "address", - "name": "_operator", - "type": "address" - } + {"internalType": "address", "name": "_muon", "type": "address"}, + {"internalType": "address", "name": "_muonValidGateway", "type": "address"}, + {"internalType": "address", "name": "_admin", "type": "address"}, + {"internalType": "address", "name": "_operator", "type": "address"}, ], "stateMutability": "nonpayable", - "type": "constructor" + "type": "constructor", }, { + "anonymous": False, "inputs": [ - { - "internalType": "address", - "name": "have", - "type": "address" - }, - { - "internalType": "address", - "name": "want", - "type": "address" - } + {"indexed": True, "internalType": "address", "name": "user", "type": "address"}, + {"indexed": False, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": False, "internalType": "uint256", "name": "multiplier", "type": "uint256"}, ], - "name": "OnlyCoordinatorCanFulfill", - "type": "error" + "name": "Participate", + "type": "event", + }, + { + "anonymous": False, + "inputs": [{"indexed": False, "internalType": "address", "name": "account", "type": "address"}], + "name": "Paused", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } + {"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": True, "internalType": "address", "name": "winner", "type": "address"}, + ], + "name": "PrizeClaimed", + "type": "event", + }, + { + "anonymous": False, + "inputs": [{"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "PrizeRefunded", + "type": "event", + }, + { + "anonymous": False, + "inputs": [ + {"indexed": True, "internalType": "address", "name": "initiator", "type": "address"}, + {"indexed": False, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + ], + "name": "RaffleCreated", + "type": "event", + }, + { + "anonymous": False, + "inputs": [ + {"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": True, "internalType": "address", "name": "rejector", "type": "address"}, + ], + "name": "RaffleRejected", + "type": "event", + }, + { + "anonymous": False, + "inputs": [ + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "previousAdminRole", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "newAdminRole", "type": "bytes32"}, ], "name": "RoleAdminChanged", - "type": "event" + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], "name": "RoleGranted", - "type": "event" + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], "name": "RoleRevoked", - "type": "event" + "type": "event", }, { "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": False, - "internalType": "uint256[]", - "name": "randomWords", - "type": "uint256[]" - } - ], - "name": "VRFRequestFulfilled", - "type": "event" + "inputs": [{"indexed": False, "internalType": "address", "name": "account", "type": "address"}], + "name": "Unpaused", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } + {"indexed": True, "internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"indexed": False, "internalType": "uint256", "name": "fromId", "type": "uint256"}, + {"indexed": False, "internalType": "uint256", "name": "toId", "type": "uint256"}, ], - "name": "VRFRequestSent", - "type": "event" + "name": "WinnersSpecified", + "type": "event", }, { "inputs": [], "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "OPERATOR_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "name": "MAX_NUM_WINNERS", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "callbackGasLimit", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], + "name": "OPERATOR_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "chainlinkKeyHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "name": "_ERC721_RECEIVED", + "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [], - "name": "chainlinkVrfSubscriptionId", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "claimPrize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "getRandomWords", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } + {"internalType": "address", "name": "collection", "type": "address"}, + {"internalType": "uint256[]", "name": "tokenIds", "type": "uint256[]"}, + {"internalType": "uint256", "name": "maxParticipants", "type": "uint256"}, + {"internalType": "uint256", "name": "maxMultiplier", "type": "uint256"}, + {"internalType": "uint256", "name": "startTime", "type": "uint256"}, + {"internalType": "uint256", "name": "endTime", "type": "uint256"}, + {"internalType": "uint256", "name": "winnersCount", "type": "uint256"}, + {"internalType": "bytes32", "name": "requirementsHash", "type": "bytes32"}, ], - "stateMutability": "view", - "type": "function" + "name": "createRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "fromId", "type": "uint256"}, + {"internalType": "uint256", "name": "toId", "type": "uint256"}, ], + "name": "getParticipants", + "outputs": [{"internalType": "address[]", "name": "participants", "type": "address[]"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}], "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "fromId", "type": "uint256"}, + {"internalType": "uint256", "name": "toId", "type": "uint256"}, ], + "name": "getWinners", + "outputs": [{"internalType": "address[]", "name": "winners", "type": "address[]"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "getWinnersCount", + "outputs": [{"internalType": "uint256", "name": "winnersCount", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], "name": "grantRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [], - "name": "lastRequestId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + "inputs": [ + {"internalType": "address", "name": "", "type": "address"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], + "name": "isParticipated", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "randomWords", - "type": "uint256[]" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "address", "name": "", "type": "address"}, ], - "name": "rawFulfillRandomWords", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "isWinner", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "address", "name": "", "type": "address"}, ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "isWinnerClaimed", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "lastRaffleId", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "muon", + "outputs": [{"internalType": "contract IMuonClient", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "muonAppId", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "muonPublicKey", + "outputs": [ + {"internalType": "uint256", "name": "x", "type": "uint256"}, + {"internalType": "uint8", "name": "parity", "type": "uint8"}, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "muonValidGateway", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "uint32", - "name": "numWords", - "type": "uint32" - } + {"internalType": "address", "name": "", "type": "address"}, + {"internalType": "address", "name": "", "type": "address"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "bytes", "name": "", "type": "bytes"}, ], - "name": "requestRandomWords", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + "name": "onERC721Received", + "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [ + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "address", "name": "", "type": "address"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], - "stateMutability": "nonpayable", - "type": "function" + "name": "participantPositions", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "multiplier", "type": "uint256"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "signature", + "type": "tuple", }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "name": "revokeRole", + "name": "participateInRaffle", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", + }, + {"inputs": [], "name": "pause", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, + { + "inputs": [], + "name": "paused", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "uint32", - "name": "gaslimit", - "type": "uint32" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], - "name": "setCallbackGasLimit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "raffleParticipants", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "period", - "type": "uint256" - } + {"internalType": "uint256", "name": "", "type": "uint256"}, + {"internalType": "uint256", "name": "", "type": "uint256"}, ], - "name": "setValidityPeriod", + "name": "raffleWinners", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "name": "raffles", + "outputs": [ + {"internalType": "address", "name": "initiator", "type": "address"}, + {"internalType": "address", "name": "collection", "type": "address"}, + {"internalType": "uint256", "name": "maxParticipants", "type": "uint256"}, + {"internalType": "uint256", "name": "maxMultiplier", "type": "uint256"}, + {"internalType": "uint256", "name": "startTime", "type": "uint256"}, + {"internalType": "uint256", "name": "endTime", "type": "uint256"}, + {"internalType": "uint256", "name": "lastParticipantIndex", "type": "uint256"}, + {"internalType": "uint256", "name": "lastWinnerIndex", "type": "uint256"}, + {"internalType": "uint256", "name": "participantsCount", "type": "uint256"}, + {"internalType": "uint256", "name": "winnersCount", "type": "uint256"}, + {"internalType": "uint256", "name": "lastNotClaimedTokenIndex", "type": "uint256"}, + {"internalType": "bool", "name": "exists", "type": "bool"}, + {"internalType": "enum AbstractPrizetapRaffle.Status", "name": "status", "type": "uint8"}, + {"internalType": "bytes32", "name": "requirementsHash", "type": "bytes32"}, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "refundPrize", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "keyHash", - "type": "bytes32" - } - ], - "name": "setVrfKeyHash", + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "refundRemainingPrizes", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "uint16", - "name": "count", - "type": "uint16" - } - ], - "name": "setVrfRequestConfirmations", + "inputs": [{"internalType": "uint256", "name": "raffleId", "type": "uint256"}], + "name": "rejectRaffle", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint64", - "name": "id", - "type": "uint64" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "name": "setVrfSubscriptionId", + "name": "renounceRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "stateMutability": "view", - "type": "function" + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { - "inputs": [], - "name": "validityPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "inputs": [{"internalType": "address", "name": "_muonAddress", "type": "address"}], + "name": "setMuonAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { - "inputs": [], - "name": "vrfRequestConfirmations", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" + "inputs": [{"internalType": "uint256", "name": "_muonAppId", "type": "uint256"}], + "name": "setMuonAppId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "vrfRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "expirationTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numWords", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -] - -LINEA_PRIZETAP_ABI = [ + "inputs": [{"internalType": "address", "name": "_gatewayAddress", "type": "address"}], + "name": "setMuonGateway", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, { "inputs": [ - { - "internalType": "uint256", - "name": "_muonAppId", - "type": "uint256" - }, { "components": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } + {"internalType": "uint256", "name": "x", "type": "uint256"}, + {"internalType": "uint8", "name": "parity", "type": "uint8"}, ], "internalType": "struct IMuonClient.PublicKey", "name": "_muonPublicKey", - "type": "tuple" - }, - { - "internalType": "address", - "name": "_muon", - "type": "address" - }, - { - "internalType": "address", - "name": "_muonValidGateway", - "type": "address" - }, - { - "internalType": "address", - "name": "_admin", - "type": "address" - }, - { - "internalType": "address", - "name": "_operator", - "type": "address" + "type": "tuple", } ], + "name": "setMuonPublicKey", + "outputs": [], "stateMutability": "nonpayable", - "type": "constructor" + "type": "function", }, { - "anonymous": False, "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "expirationTime", "type": "uint256"}, + {"internalType": "uint256[]", "name": "randomNumbers", "type": "uint256[]"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "indexed": True, - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "signature", + "type": "tuple", }, - { - "indexed": False, - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - } + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "name": "Participate", - "type": "event" + "name": "setRaffleRandomNumbers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "periodSeconds", "type": "uint256"}], + "name": "setValidationPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { - "anonymous": False, "inputs": [ - { - "indexed": False, - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "toId", "type": "uint256"}, ], - "name": "Paused", - "type": "event" + "name": "setWinners", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], + "name": "supportsInterface", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", + }, + {"inputs": [], "name": "unpause", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, + { + "inputs": [], + "name": "validationPeriod", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", }, { - "anonymous": False, "inputs": [ + {"internalType": "uint256", "name": "raffleId", "type": "uint256"}, + {"internalType": "uint256", "name": "multiplier", "type": "uint256"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "sign", + "type": "tuple", }, - { - "indexed": True, - "internalType": "address", - "name": "winner", - "type": "address" - } + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "name": "PrizeClaimed", - "type": "event" + "name": "verifyParticipationSig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { - "anonymous": False, "inputs": [ + {"internalType": "uint256", "name": "expirationTime", "type": "uint256"}, + {"internalType": "uint256[]", "name": "randomNumbers", "type": "uint256[]"}, + {"internalType": "bytes", "name": "reqId", "type": "bytes"}, { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } + "components": [ + {"internalType": "uint256", "name": "signature", "type": "uint256"}, + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "nonce", "type": "address"}, + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "sign", + "type": "tuple", + }, + {"internalType": "bytes", "name": "gatewaySignature", "type": "bytes"}, ], - "name": "PrizeRefunded", - "type": "event" + "name": "verifyRandomNumberSig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, +] + +UNITAP_PASS_ABI = [ + {"inputs": [], "stateMutability": "nonpayable", "type": "constructor"}, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "indexed": False, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } + {"indexed": True, "internalType": "address", "name": "owner", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "approved", "type": "address"}, + {"indexed": True, "internalType": "uint256", "name": "tokenId", "type": "uint256"}, ], - "name": "RaffleCreated", - "type": "event" + "name": "Approval", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address", - "name": "rejector", - "type": "address" - } + {"indexed": True, "internalType": "address", "name": "owner", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "operator", "type": "address"}, + {"indexed": False, "internalType": "bool", "name": "approved", "type": "bool"}, ], - "name": "RaffleRejected", - "type": "event" + "name": "ApprovalForAll", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "previousAdminRole", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "newAdminRole", "type": "bytes32"}, ], "name": "RoleAdminChanged", - "type": "event" + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], "name": "RoleGranted", - "type": "event" + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": True, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], "name": "RoleRevoked", - "type": "event" + "type": "event", }, { "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "Unpaused", - "type": "event" + "inputs": [{"indexed": False, "internalType": "string", "name": "baseURI", "type": "string"}], + "name": "SetBaseURI", + "type": "event", }, { "anonymous": False, "inputs": [ - { - "indexed": True, - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "indexed": True, - "internalType": "address[]", - "name": "winner", - "type": "address[]" - } + {"indexed": True, "internalType": "address", "name": "from", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "to", "type": "address"}, + {"indexed": True, "internalType": "uint256", "name": "tokenId", "type": "uint256"}, ], - "name": "WinnersSpecified", - "type": "event" + "name": "Transfer", + "type": "event", }, { "inputs": [], "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "MAX_NUM_WINNERS", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } + "name": "MINTER_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + {"internalType": "address", "name": "to", "type": "address"}, + {"internalType": "uint256", "name": "tokenId", "type": "uint256"}, ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "address", "name": "owner", "type": "address"}], + "name": "balanceOf", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "OPERATOR_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } + "name": "baseURI", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "tokenId", "type": "uint256"}], + "name": "getApproved", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}], + "name": "getRoleAdmin", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], + "name": "hasRole", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [], - "name": "_ERC721_RECEIVED", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } + "inputs": [ + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "operator", "type": "address"}, ], + "name": "isApprovedForAll", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], "stateMutability": "view", - "type": "function" + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "tokenId", "type": "uint256"}], + "name": "ownerOf", + "outputs": [{"internalType": "address", "name": "", "type": "address"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "_raffleId", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "_participants", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "_multipliers", - "type": "uint256[]" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "name": "addParticipants", + "name": "renounceRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "name": "claimPrize", + "name": "revokeRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", + }, + { + "inputs": [{"internalType": "address", "name": "to", "type": "address"}], + "name": "safeMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "maxParticipants", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "startTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "winnersCount", - "type": "uint32" - }, - { - "internalType": "bytes32", - "name": "requirementsHash", - "type": "bytes32" - } + {"internalType": "address", "name": "from", "type": "address"}, + {"internalType": "address", "name": "to", "type": "address"}, + {"internalType": "uint256", "name": "tokenId", "type": "uint256"}, ], - "name": "createRaffle", + "name": "safeTransferFrom", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expirationTime", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "randomNumbers", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } - ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } + {"internalType": "address", "name": "from", "type": "address"}, + {"internalType": "address", "name": "to", "type": "address"}, + {"internalType": "uint256", "name": "tokenId", "type": "uint256"}, + {"internalType": "bytes", "name": "data", "type": "bytes"}, ], - "name": "drawRaffle", + "name": "safeTransferFrom", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "getParticipants", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } + {"internalType": "address", "name": "operator", "type": "address"}, + {"internalType": "bool", "name": "approved", "type": "bool"}, ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "string", "name": "baseURI_", "type": "string"}], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], + "name": "supportsInterface", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], + "inputs": [], + "name": "symbol", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } - ], - "name": "getWinners", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } - ], + "inputs": [], + "name": "tokenIdCounter", + "outputs": [{"internalType": "uint256", "name": "idCounter", "type": "uint256"}], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [{"internalType": "uint256", "name": "tokenId", "type": "uint256"}], + "name": "tokenURI", + "outputs": [{"internalType": "string", "name": "", "type": "string"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "address", "name": "from", "type": "address"}, + {"internalType": "address", "name": "to", "type": "address"}, + {"internalType": "uint256", "name": "tokenId", "type": "uint256"}, ], - "name": "grantRole", + "name": "transferFrom", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, +] + +VRF_CLIENT_ABI = [ { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + {"internalType": "address", "name": "_chainlinkVRFCoordinator", "type": "address"}, + {"internalType": "uint64", "name": "_chainlinkVRFSubscriptionId", "type": "uint64"}, + {"internalType": "bytes32", "name": "_chainlinkKeyHash", "type": "bytes32"}, + {"internalType": "address", "name": "_admin", "type": "address"}, + {"internalType": "address", "name": "_operator", "type": "address"}, ], - "stateMutability": "view", - "type": "function" + "stateMutability": "nonpayable", + "type": "constructor", }, { "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "isParticipated", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + {"internalType": "address", "name": "have", "type": "address"}, + {"internalType": "address", "name": "want", "type": "address"}, ], - "stateMutability": "view", - "type": "function" + "name": "OnlyCoordinatorCanFulfill", + "type": "error", }, { + "anonymous": False, "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "previousAdminRole", "type": "bytes32"}, + {"indexed": True, "internalType": "bytes32", "name": "newAdminRole", "type": "bytes32"}, ], - "name": "isWinner", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + "name": "RoleAdminChanged", + "type": "event", + }, + { + "anonymous": False, + "inputs": [ + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], - "stateMutability": "view", - "type": "function" + "name": "RoleGranted", + "type": "event", }, { + "anonymous": False, "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } + {"indexed": True, "internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"indexed": True, "internalType": "address", "name": "account", "type": "address"}, + {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, ], - "name": "isWinnerClaimed", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + "name": "RoleRevoked", + "type": "event", + }, + { + "anonymous": False, + "inputs": [ + {"indexed": False, "internalType": "uint256", "name": "requestId", "type": "uint256"}, + {"indexed": False, "internalType": "uint256[]", "name": "randomWords", "type": "uint256[]"}, ], - "stateMutability": "view", - "type": "function" + "name": "VRFRequestFulfilled", + "type": "event", + }, + { + "anonymous": False, + "inputs": [{"indexed": False, "internalType": "uint256", "name": "requestId", "type": "uint256"}], + "name": "VRFRequestSent", + "type": "event", }, { "inputs": [], - "name": "lastRaffleId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "muon", - "outputs": [ - { - "internalType": "contract IMuonClient", - "name": "", - "type": "address" - } - ], + "name": "OPERATOR_ROLE", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "muonAppId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "name": "callbackGasLimit", + "outputs": [{"internalType": "uint32", "name": "", "type": "uint32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "muonPublicKey", - "outputs": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } - ], + "name": "chainlinkKeyHash", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "muonValidGateway", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], + "name": "chainlinkVrfSubscriptionId", + "outputs": [{"internalType": "uint64", "name": "", "type": "uint64"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" + "inputs": [{"internalType": "uint256", "name": "requestId", "type": "uint256"}], + "name": "getRandomWords", + "outputs": [{"internalType": "uint256[]", "name": "", "type": "uint256[]"}], + "stateMutability": "view", + "type": "function", }, { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "participantPositions", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "inputs": [{"internalType": "bytes32", "name": "role", "type": "bytes32"}], + "name": "getRoleAdmin", + "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } - ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "signature", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "name": "participateInRaffle", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "pause", + "name": "grantRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [], - "name": "paused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } + "inputs": [ + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], + "name": "hasRole", + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "raffles", - "outputs": [ - { - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxParticipants", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxMultiplier", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "startTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "participantsCount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "winnersCount", - "type": "uint32" - }, - { - "internalType": "bool", - "name": "exists", - "type": "bool" - }, - { - "internalType": "enum AbstractPrizetapRaffle.Status", - "name": "status", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "requirementsHash", - "type": "bytes32" - } - ], + "inputs": [], + "name": "lastRequestId", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } + {"internalType": "uint256", "name": "requestId", "type": "uint256"}, + {"internalType": "uint256[]", "name": "randomWords", "type": "uint256[]"}, ], - "name": "refundPrize", + "name": "rawFulfillRandomWords", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], - "name": "rejectRaffle", + "name": "renounceRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], + "inputs": [{"internalType": "uint32", "name": "numWords", "type": "uint32"}], + "name": "requestRandomWords", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } + {"internalType": "bytes32", "name": "role", "type": "bytes32"}, + {"internalType": "address", "name": "account", "type": "address"}, ], "name": "revokeRole", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "address", - "name": "_muonAddress", - "type": "address" - } - ], - "name": "setMuonAddress", + "inputs": [{"internalType": "uint32", "name": "gaslimit", "type": "uint32"}], + "name": "setCallbackGasLimit", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "uint256", - "name": "_muonAppId", - "type": "uint256" - } - ], - "name": "setMuonAppId", + "inputs": [{"internalType": "uint256", "name": "period", "type": "uint256"}], + "name": "setValidityPeriod", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "address", - "name": "_gatewayAddress", - "type": "address" - } - ], - "name": "setMuonGateway", + "inputs": [{"internalType": "bytes32", "name": "keyHash", "type": "bytes32"}], + "name": "setVrfKeyHash", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "x", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "parity", - "type": "uint8" - } - ], - "internalType": "struct IMuonClient.PublicKey", - "name": "_muonPublicKey", - "type": "tuple" - } - ], - "name": "setMuonPublicKey", + "inputs": [{"internalType": "uint16", "name": "count", "type": "uint16"}], + "name": "setVrfRequestConfirmations", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "uint256", - "name": "periodSeconds", - "type": "uint256" - } - ], - "name": "setValidationPeriod", + "inputs": [{"internalType": "uint64", "name": "id", "type": "uint64"}], + "name": "setVrfSubscriptionId", "outputs": [], "stateMutability": "nonpayable", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], + "inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { "inputs": [], - "name": "unpause", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "name": "validityPeriod", + "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "stateMutability": "view", + "type": "function", }, { "inputs": [], - "name": "validationPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "name": "vrfRequestConfirmations", + "outputs": [{"internalType": "uint16", "name": "", "type": "uint16"}], "stateMutability": "view", - "type": "function" + "type": "function", }, { - "inputs": [ - { - "internalType": "uint256", - "name": "raffleId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } - ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "sign", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } + "inputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], + "name": "vrfRequests", + "outputs": [ + {"internalType": "uint256", "name": "expirationTime", "type": "uint256"}, + {"internalType": "uint256", "name": "numWords", "type": "uint256"}, ], - "name": "verifyParticipationSig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "stateMutability": "view", + "type": "function", }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expirationTime", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "randomNumbers", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "reqId", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "signature", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "nonce", - "type": "address" - } - ], - "internalType": "struct IMuonClient.SchnorrSign", - "name": "sign", - "type": "tuple" - }, - { - "internalType": "bytes", - "name": "gatewaySignature", - "type": "bytes" - } - ], - "name": "verifyRandomNumberSig", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } ] VRF_CLIENT_POLYGON_ADDRESS = "0xD1E7877A1C3F782dec76FB58C2B926365433d46F" CONTRACT_ADDRESSES = { - '137': { - 'erc20_prizetap_addr': "0xB521C36F76d28Edb287346C9D649Fa1A60754f04", - "erc721_prizetap_addr": "0xb68D3f2946Bf477978c68b509FD9f85E9e20F869" - }, - '80001': { - 'erc20_prizetap_addr': "0x5AD9BAf388E6E4F7c40652e21545F700C2104FF0", - "erc721_prizetap_addr": "0x9E5c0d8a54D93956f26935447BBADd629f13a0dE" - } -} \ No newline at end of file + "137": { + "erc20_prizetap_addr": "0xB521C36F76d28Edb287346C9D649Fa1A60754f04", + "erc721_prizetap_addr": "0xb68D3f2946Bf477978c68b509FD9f85E9e20F869", + }, + "80001": { + "erc20_prizetap_addr": "0x5AD9BAf388E6E4F7c40652e21545F700C2104FF0", + "erc721_prizetap_addr": "0x9E5c0d8a54D93956f26935447BBADd629f13a0dE", + }, +} diff --git a/prizetap/migrations/0036_raffle_winners_count.py b/prizetap/migrations/0036_raffle_winners_count.py new file mode 100644 index 00000000..e767d53b --- /dev/null +++ b/prizetap/migrations/0036_raffle_winners_count.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.4 on 2023-10-26 08:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('prizetap', '0035_alter_raffle_status'), + ] + + operations = [ + migrations.AddField( + model_name='raffle', + name='winners_count', + field=models.IntegerField(default=1), + ), + ] diff --git a/prizetap/migrations/0037_alter_raffle_status.py b/prizetap/migrations/0037_alter_raffle_status.py new file mode 100644 index 00000000..e644addc --- /dev/null +++ b/prizetap/migrations/0037_alter_raffle_status.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.4 on 2023-10-26 13:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('prizetap', '0036_raffle_winners_count'), + ] + + operations = [ + migrations.AlterField( + model_name='raffle', + name='status', + field=models.CharField(choices=[('PENDING', 'Pending'), ('REJECTED', 'Rejected'), ('VERIFIED', 'Verified'), ('RWS', 'Random words are set'), ('WS', 'Winners are set'), ('CLOSED', 'Closed')], default='PENDING', max_length=10), + ), + ] diff --git a/prizetap/models.py b/prizetap/models.py index 3082e0e4..3b8cc83a 100644 --- a/prizetap/models.py +++ b/prizetap/models.py @@ -1,21 +1,23 @@ from django.db import models -from faucet.models import Chain -from faucet.constraints import OptimismDonationConstraint, OptimismClaimingGasConstraint from django.utils import timezone from django.utils.translation import gettext_lazy as _ + from authentication.models import NetworkTypes, UserProfile from core.models import BigNumField, UserConstraint -from .constraints import * +from faucet.constraints import OptimismClaimingGasConstraint, OptimismDonationConstraint +from faucet.models import Chain + +from .constraints import HaveUnitapPass, NotHaveUnitapPass # Create your models here. class Constraint(UserConstraint): constraints = UserConstraint.constraints + [ - HaveUnitapPass, + HaveUnitapPass, NotHaveUnitapPass, OptimismDonationConstraint, - OptimismClaimingGasConstraint + OptimismClaimingGasConstraint, ] name = UserConstraint.create_name_field(constraints) @@ -25,14 +27,12 @@ class Status(models.TextChoices): PENDING = "PENDING", _("Pending") REJECTED = "REJECTED", _("Rejected") VERIFIED = "VERIFIED", _("Verified") - HELD = "HELD", _("Held") + RANDOM_WORDS_SET = "RWS", _("Random words are set") + WINNERS_SET = "WS", _("Winners are set") CLOSED = "CLOSED", _("Closed") - WINNER_SET = "WS", _("Winner is set") class Meta: - models.UniqueConstraint( - fields=["chain", "contract", "raffleId"], name="unique_raffle" - ) + models.UniqueConstraint(fields=["chain", "contract", "raffleId"], name="unique_raffle") name = models.CharField(max_length=256) description = models.TextField(null=True, blank=True) @@ -66,10 +66,9 @@ class Meta: deadline = models.DateTimeField() max_number_of_entries = models.IntegerField() max_multiplier = models.IntegerField(default=1) + winners_count = models.IntegerField(default=1) - status = models.CharField( - max_length=10, choices=Status.choices, default=Status.PENDING - ) + status = models.CharField(max_length=10, choices=Status.choices, default=Status.PENDING) rejection_reason = models.TextField(null=True, blank=True) tx_hash = models.CharField(max_length=255, blank=True, null=True) vrf_tx_hash = models.CharField(max_length=255, blank=True, null=True) @@ -124,10 +123,9 @@ def winner_entry(self): def __str__(self): return f"{self.name}" - + def save(self, *args, **kwargs): - if self.status == self.Status.VERIFIED \ - and not self.raffleId: + if self.status == self.Status.VERIFIED and not self.raffleId: raise Exception("The raffleId of a verified raffle can't be empty") super().save(*args, **kwargs) @@ -139,9 +137,7 @@ class Meta: verbose_name_plural = "raffle entries" raffle = models.ForeignKey(Raffle, on_delete=models.CASCADE, related_name="entries") - user_profile = models.ForeignKey( - UserProfile, on_delete=models.CASCADE, related_name="raffle_entries" - ) + user_profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name="raffle_entries") created_at = models.DateTimeField(auto_now_add=True, editable=True) @@ -161,16 +157,6 @@ def user(self): def age(self): return timezone.now() - self.created_at - def save(self, *args, **kwargs): - if self.is_winner: - try: - entry = RaffleEntry.objects.get(is_winner=True, raffle=self.raffle) - assert entry.pk == self.pk, "The raffle already has a winner" - except RaffleEntry.DoesNotExist: - pass - - super().save(*args, **kwargs) - class LineaRaffleEntries(models.Model): wallet_address = models.CharField(max_length=255) @@ -179,4 +165,4 @@ class LineaRaffleEntries(models.Model): claim_tx = models.CharField(max_length=255, blank=True, null=True) def __str__(self): - return str(self.wallet_address) \ No newline at end of file + return str(self.wallet_address) diff --git a/prizetap/serializers.py b/prizetap/serializers.py index 897136ca..6136eb61 100644 --- a/prizetap/serializers.py +++ b/prizetap/serializers.py @@ -1,11 +1,16 @@ -import json +# flake8: noqa import base64 +import json + from rest_framework import serializers -from core.serializers import UserConstraintBaseSerializer + from authentication.serializers import SimpleProfilerSerializer +from core.serializers import UserConstraintBaseSerializer from faucet.serializers import SmallChainSerializer + +from .constraints import * from .models import * -from .constants import * + class ConstraintSerializer(UserConstraintBaseSerializer, serializers.ModelSerializer): class Meta(UserConstraintBaseSerializer.Meta): @@ -16,6 +21,7 @@ def get_params(self, constraint: UserConstraint): c_class: ConstraintVerification = eval(constraint.name) return [p.name for p in c_class.param_keys()] + class SimpleRaffleSerializer(serializers.ModelSerializer): class Meta: model = Raffle @@ -32,11 +38,13 @@ class Meta: "raffleId", ] + class RaffleEntrySerializer(serializers.ModelSerializer): raffle = SimpleRaffleSerializer() user_profile = SimpleProfilerSerializer() chain = serializers.SerializerMethodField() wallet = serializers.SerializerMethodField() + class Meta: model = RaffleEntry fields = [ @@ -48,7 +56,7 @@ class Meta: "created_at", "multiplier", "tx_hash", - "claiming_prize_tx" + "claiming_prize_tx", ] read_only_fields = [ "pk", @@ -62,25 +70,18 @@ class Meta: def get_chain(self, entry: RaffleEntry): return entry.raffle.chain.chain_id - + def get_wallet(self, entry: RaffleEntry): - return entry.user_profile.wallets.get( - wallet_type=entry.raffle.chain.chain_type).address + return entry.user_profile.wallets.get(wallet_type=entry.raffle.chain.chain_type).address + class WinnerEntrySerializer(serializers.ModelSerializer): user_profile = SimpleProfilerSerializer() wallet = serializers.SerializerMethodField() + class Meta: model = RaffleEntry - fields = [ - "pk", - "user_profile", - "wallet", - "created_at", - "multiplier", - "tx_hash", - "claiming_prize_tx" - ] + fields = ["pk", "user_profile", "wallet", "created_at", "multiplier", "tx_hash", "claiming_prize_tx"] read_only_fields = [ "pk", "user_profile", @@ -90,13 +91,13 @@ class Meta: ] def get_wallet(self, entry: RaffleEntry): - return entry.user_profile.wallets.get( - wallet_type=entry.raffle.chain.chain_type).address + return entry.user_profile.wallets.get(wallet_type=entry.raffle.chain.chain_type).address + class CreateRaffleSerializer(serializers.ModelSerializer): class Meta: model = Raffle - fields = '__all__' + fields = "__all__" read_only_fields = [ "pk", @@ -105,13 +106,13 @@ class Meta: "created_at", "status", "rejection_reason", - "is_active" + "is_active", ] def validate(self, data): - constraints = data['constraints'] - constraint_params = json.loads(base64.b64decode(data['constraint_params'])) - data['constraint_params'] = base64.b64decode(data['constraint_params']).decode("utf-8") + constraints = data["constraints"] + constraint_params = json.loads(base64.b64decode(data["constraint_params"])) + data["constraint_params"] = base64.b64decode(data["constraint_params"]).decode("utf-8") if len(constraints) != 0: for c in constraints: constraint_class: ConstraintVerification = eval(c.name) @@ -119,14 +120,11 @@ def validate(self, data): if len(constraint_class.param_keys()) != 0: constraint_class.is_valid_param_keys(constraint_params[c.name]) except KeyError as e: - raise serializers.ValidationError({ - "constraint_params": [{ - f"{c.name}": str(e) - }] - }) - data['creator_profile'] = self.context['user_profile'] + raise serializers.ValidationError({"constraint_params": [{f"{c.name}": str(e)}]}) + data["creator_profile"] = self.context["user_profile"] return data + class RaffleSerializer(serializers.ModelSerializer): chain = SmallChainSerializer() winner_entry = WinnerEntrySerializer() @@ -174,14 +172,12 @@ class Meta: "user_entry", "number_of_entries", "number_of_onchain_entries", - "max_multiplier" + "max_multiplier", ] - + def get_user_entry(self, raffle: Raffle): try: - return RaffleEntrySerializer( - raffle.entries.get(user_profile=self.context['user']) - ).data + return RaffleEntrySerializer(raffle.entries.get(user_profile=self.context["user"])).data except RaffleEntry.DoesNotExist: return None @@ -189,4 +185,4 @@ def get_user_entry(self, raffle: Raffle): class LineaRaffleEntrySerializer(serializers.ModelSerializer): class Meta: model = LineaRaffleEntries - fields = "__all__" \ No newline at end of file + fields = "__all__" diff --git a/prizetap/tasks.py b/prizetap/tasks.py index fcba9fcb..9a1ebb09 100644 --- a/prizetap/tasks.py +++ b/prizetap/tasks.py @@ -1,18 +1,17 @@ +import time + import requests from celery import shared_task from django.utils import timezone + from core.helpers import memcache_lock -from .models import Raffle, Chain -from .utils import ( - PrizetapContractClient, - VRFClientContractClient, - LineaPrizetapContractClient -) +from .models import Raffle +from .utils import PrizetapContractClient, VRFClientContractClient -@shared_task(bind=True) -def draw_the_expired_raffles(self): +@shared_task(bind=True) +def set_raffle_random_words(self): id = f"{self.name}-LOCK" with memcache_lock(id, self.app.oid) as acquired: @@ -20,27 +19,56 @@ def draw_the_expired_raffles(self): print(f"Could not acquire process lock at {self.name}") return - raffles_queryset = ( - Raffle.objects - .filter(deadline__lt=timezone.now()) - .filter(status=Raffle.Status.PENDING) + raffle = ( + Raffle.objects.filter(deadline__lt=timezone.now()) + .filter(status=Raffle.Status.VERIFIED) + .filter(vrf_tx_hash__isnull=False) + .first() ) - if raffles_queryset.count() > 0: - for raffle in raffles_queryset: - if raffle.number_of_onchain_entries > 0 and not raffle.winner_entry: - print(f"Drawing the raffle {raffle.name}") - raffle_client = PrizetapContractClient(raffle) - tx_hash = raffle_client.draw_raffle() - receipt = raffle_client.wait_for_transaction_receipt( - tx_hash) - if receipt['status'] == 1: - raffle.status = Raffle.Status.HELD - raffle.save() + if raffle: + print(f"Setting the raffle {raffle.name} random words") + vrf_client = VRFClientContractClient(raffle.chain) + last_request = vrf_client.get_last_request() + expiration_time = last_request[0] + now = int(time.time()) + if now < expiration_time: + set_random_words(raffle) + else: + print("Random words have expired") + raffle.vrf_tx_hash = None + raffle.save() + + +def set_random_words(raffle: Raffle): + muon_response = requests.get( + f"https://shield.unitap.app/v1/?app=stage_unitap&method=random-words&\ + params[chainId]={raffle.chain.chain_id}¶ms[prizetapRaffle]={raffle.contract}&\ + params[raffleId]={raffle.raffleId}" + ) + muon_response = muon_response.json() + if muon_response["success"]: + muon_response = muon_response["result"] + muon_data = muon_response["data"]["result"] + raffle_client = PrizetapContractClient(raffle) + random_words = [int(r) for r in muon_data["randomWords"]] + raffle_client.set_raffle_random_words( + int(muon_data["expirationTime"]), + random_words, + muon_response["reqId"], + ( + int(muon_response["signatures"][0]["signature"], 16), + muon_response["signatures"][0]["owner"], + muon_response["data"]["init"]["nonceAddress"], + ), + muon_response["shieldSignature"], + ) + raffle.status = Raffle.Status.RANDOM_WORDS_SET + raffle.save() -@shared_task(bind=True) -def set_the_winner_of_raffles(self): +@shared_task(bind=True) +def set_raffle_winners(self): id = f"{self.name}-LOCK" with memcache_lock(id, self.app.oid) as acquired: @@ -48,31 +76,21 @@ def set_the_winner_of_raffles(self): print(f"Could not acquire process lock at {self.name}") return - raffles_queryset = ( - Raffle.objects - .filter(deadline__lt=timezone.now()) - .filter(status=Raffle.Status.HELD) + raffles_queryset = Raffle.objects.filter(deadline__lt=timezone.now()).filter( + status=Raffle.Status.RANDOM_WORDS_SET ) if raffles_queryset.count() > 0: for raffle in raffles_queryset: - print(f"Setting the winner of raffle {raffle.name}") + print(f"Setting the raffle {raffle.name} winners") raffle_client = PrizetapContractClient(raffle) - winner_address = raffle_client.get_raffle_winner() - if winner_address and winner_address != "0x0000000000000000000000000000000000000000": - try: - winner_entry = raffle.entries.filter( - user_profile__wallets__address__iexact=winner_address).get() - winner_entry.is_winner = True - winner_entry.save() - raffle.status = Raffle.Status.WINNER_SET - raffle.save() - except Exception as e: - print(e) - pass + tx_hash = raffle_client.set_winners() + if tx_hash: + raffle.status = Raffle.Status.WINNERS_SET + raffle.save() -@shared_task(bind=True) -def request_random_words_for_expired_linea_raffles(self): +@shared_task(bind=True) +def get_raffle_winners(self): id = f"{self.name}-LOCK" with memcache_lock(id, self.app.oid) as acquired: @@ -80,31 +98,23 @@ def request_random_words_for_expired_linea_raffles(self): print(f"Could not acquire process lock at {self.name}") return - raffles_queryset = ( - Raffle.objects - .filter(deadline__lt=timezone.now()) - .filter(chain__chain_id=59140) - .filter(status=Raffle.Status.PENDING) - .filter(vrf_tx_hash__isnull=True) - ) + raffles_queryset = Raffle.objects.filter(deadline__lt=timezone.now()).filter(status=Raffle.Status.WINNERS_SET) if raffles_queryset.count() > 0: for raffle in raffles_queryset: - if raffle.linea_entries.count() > 0: - print(f"Request a random number for the Linea raffle {raffle.name}") - request_random_words_for_linea_raffle(raffle) - -def request_random_words_for_linea_raffle(raffle: Raffle): - chain = Chain.objects.get(chain_id=80001) - vrf_client = VRFClientContractClient(chain) - raffle_client = LineaPrizetapContractClient(raffle) - winners_count = raffle_client.get_raffle_winners_count() - tx_hash = vrf_client.request_random_words(winners_count) - raffle.vrf_tx_hash = tx_hash - raffle.save() + print(f"Getting the winner of raffle {raffle.name}") + raffle_client = PrizetapContractClient(raffle) + winner_addresses = raffle_client.get_raffle_winners() + for addr in winner_addresses: + if addr and addr != "0x0000000000000000000000000000000000000000": + winner_entry = raffle.entries.filter(user_profile__wallets__address__iexact=addr).get() + winner_entry.is_winner = True + winner_entry.save() + raffle.status = Raffle.Status.CLOSED + raffle.save() -@shared_task(bind=True) -def draw_expired_linea_raffles(self): +@shared_task(bind=True) +def request_random_words_for_expired_raffles(self): id = f"{self.name}-LOCK" with memcache_lock(id, self.app.oid) as acquired: @@ -113,77 +123,23 @@ def draw_expired_linea_raffles(self): return raffles_queryset = ( - Raffle.objects - .filter(deadline__lt=timezone.now()) - .filter(chain__chain_id=59140) - .filter(status=Raffle.Status.PENDING) - .filter(vrf_tx_hash__isnull=False) + Raffle.objects.filter(deadline__lt=timezone.now()) + .filter(status=Raffle.Status.VERIFIED) + .filter(vrf_tx_hash__isnull=True) ) if raffles_queryset.count() > 0: for raffle in raffles_queryset: - if raffle.linea_entries.count() > 0: - print(f"Drawing the Linea raffle {raffle.name}") - draw_linea_raffle(raffle) + if raffle.number_of_onchain_entries > 0: + print(f"Request random words for the raffle {raffle.name}") + request_random_words(raffle) + break -def draw_linea_raffle(raffle: Raffle): - muon_response = requests.get( - f"https://shield.unitap.app/v1/?app=stage_unitap&method=random-words¶ms[chainId]={raffle.chain.chain_id}¶ms[prizetapRaffle]={raffle.contract}¶ms[raffleId]={raffle.raffleId}" - ) - muon_response = muon_response.json() - if muon_response['success']: - muon_response = muon_response['result'] - muon_data = muon_response['data']['result'] - raffle_client = LineaPrizetapContractClient(raffle) - random_words = [int(r) for r in muon_data['randomWords']] - tx_hash = raffle_client.draw_raffle( - int(muon_data['expirationTime']), - random_words, - muon_response['reqId'], - { - "signature": muon_response['signatures'][0]['signature'], - "owner": muon_response['signatures'][0]['owner'], - "nonce": muon_response['data']['init']['nonceAddress'] - }, - muon_response['shieldSignature'] - ) - print(tx_hash) - raffle.status = Raffle.Status.CLOSED +def request_random_words(raffle: Raffle): + vrf_client = VRFClientContractClient(raffle.chain) + raffle_client = PrizetapContractClient(raffle) + winners_count = raffle_client.get_raffle_winners_count() + tx_hash = vrf_client.request_random_words(winners_count) + if tx_hash: + raffle.vrf_tx_hash = tx_hash raffle.save() - - -@shared_task(bind=True) -def set_the_winner_of_linea_raffles(self): - - id = f"{self.name}-LOCK" - - with memcache_lock(id, self.app.oid) as acquired: - if not acquired: - print(f"Could not acquire process lock at {self.name}") - return - - raffles_queryset = ( - Raffle.objects - .filter(deadline__lt=timezone.now()) - .filter(chain__chain_id=59140) - .filter(status=Raffle.Status.CLOSED) - ) - if raffles_queryset.count() > 0: - for raffle in raffles_queryset: - print(f"Setting the winners of Linea raffle {raffle.name}") - set_the_winners_of_linea_raffle(raffle) - - -def set_the_winners_of_linea_raffle(raffle: Raffle): - raffle_client = LineaPrizetapContractClient(raffle) - winner_addresses = raffle_client.get_raffle_winners() - for address in winner_addresses: - try: - winner_entry = raffle.linea_entries.filter(wallet_address=address).get() - winner_entry.is_winner = True - winner_entry.save() - except Exception as e: - print(e) - pass - raffle.status = Raffle.Status.WINNER_SET - raffle.save() \ No newline at end of file diff --git a/prizetap/tests.py b/prizetap/tests.py index b516bd1e..c8846783 100644 --- a/prizetap/tests.py +++ b/prizetap/tests.py @@ -1,14 +1,18 @@ -from unittest.mock import patch, PropertyMock +# flake8: noqa +from unittest.mock import PropertyMock, patch + +from django.contrib.auth.models import User from django.urls import reverse from django.utils import timezone -from django.contrib.auth.models import User from rest_framework.test import APITestCase + from authentication.models import NetworkTypes, UserProfile, Wallet from faucet.models import Chain, WalletAccount -from .models import * + from .constraints import * -from .utils import PrizetapContractClient +from .models import * +# from .utils import PrizetapContractClient test_wallet_key = "f57fecd11c6034fd2665d622e866f05f9b07f35f253ebd5563e3d7e76ae66809" test_rpc_url_private = "https://rpc.ankr.com/eth_sepolia" @@ -19,13 +23,11 @@ # # Create your tests here. + class BaseTestCase(APITestCase): def setUp(self): self.user_profile = UserProfile.objects.create( - user=User.objects.create_user( - username="test", - password="1234" - ), + user=User.objects.create_user(username="test", password="1234"), initial_context_id="test", username="test", ) @@ -48,12 +50,12 @@ def setUp(self): native_currency_name="ETH", symbol="ETH", chain_id="11155111", - max_claim_amount=1e11 + max_claim_amount=1e11, ) self.meet_constraint = Constraint.objects.create( name=BrightIDMeetVerification.__name__, title="BrightID meet", - description="You have to be BrightID verified." + description="You have to be BrightID verified.", ) @@ -74,7 +76,7 @@ def setUp(self): chain=self.chain, deadline=timezone.now() + timezone.timedelta(days=1), max_number_of_entries=2, - status=Raffle.Status.VERIFIED + status=Raffle.Status.VERIFIED, ) self.raffle.constraints.set([self.meet_constraint]) @@ -82,8 +84,7 @@ def test_raffle_creation(self): self.assertEqual(Raffle.objects.count(), 1) self.assertEqual(Raffle.objects.first(), self.raffle) self.assertEqual(Raffle.objects.first().constraints.count(), 1) - self.assertEqual(Raffle.objects.first( - ).constraints.first(), self.meet_constraint) + self.assertEqual(Raffle.objects.first().constraints.first(), self.meet_constraint) def test_raffle_claimable(self): self.assertTrue(self.raffle.is_claimable) @@ -103,7 +104,7 @@ def test_raffle_is_active(self): self.assertFalse(self.raffle.is_active) self.assertFalse(self.raffle.is_claimable) - @patch('prizetap.models.Raffle.is_maxed_out') + @patch("prizetap.models.Raffle.is_maxed_out") def test_raffle_claimable_if_maxed_out(self, mock_method): mock_method.return_value = True self.assertTrue(self.raffle.is_maxed_out) @@ -111,13 +112,7 @@ def test_raffle_claimable_if_maxed_out(self, mock_method): def test_raffle_maxed_out(self): self.raffle.entries.set( - [ - RaffleEntry.objects.create( - raffle=self.raffle, - user_profile=self.user_profile, - multiplier=2 - ) - ] + [RaffleEntry.objects.create(raffle=self.raffle, user_profile=self.user_profile, multiplier=2)] ) self.assertFalse(self.raffle.is_maxed_out) entry: RaffleEntry = self.raffle.entries.first() @@ -130,14 +125,11 @@ def test_raffle_maxed_out(self): RaffleEntry.objects.create( raffle=self.raffle, user_profile=UserProfile.objects.create( - user=User.objects.create_user( - username="test_2", - password="1234" - ), + user=User.objects.create_user(username="test_2", password="1234"), initial_context_id="test_2", username="test_2", ), - multiplier=1 + multiplier=1, ) self.assertTrue(self.raffle.is_maxed_out) @@ -148,36 +140,27 @@ class RaffleAPITestCase(RaffleTestCase): def setUp(self) -> None: super().setUp() - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_raffle_list(self): self.raffle.constraints.add( Constraint.objects.create( name=BrightIDAuraVerification.__name__, title="BrightID aura", - description="You have to be Aura verified." + description="You have to be Aura verified.", ) ) - response = self.client.get( - reverse("raffle-list") - ) + response = self.client.get(reverse("raffle-list")) raffle = response.data[0] self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) self.assertEqual(len(raffle["constraints"]), 2) - self.assertEqual( - raffle["constraints"][1]["name"], BrightIDAuraVerification.__name__ - ) - self.assertEqual(raffle['number_of_entries'], 0) - self.assertEqual(raffle['user_entry'], None) - self.assertEqual(raffle['winner_entry'], None) + self.assertEqual(raffle["constraints"][1]["name"], BrightIDAuraVerification.__name__) + self.assertEqual(raffle["number_of_entries"], 0) + self.assertEqual(raffle["user_entry"], None) + self.assertEqual(raffle["winner_entry"], None) def test_raffle_enrollment_authentication(self): - response = self.client.post( - reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk}) - ) + response = self.client.post(reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk})) self.assertEqual(response.status_code, 401) @patch( @@ -186,9 +169,7 @@ def test_raffle_enrollment_authentication(self): ) def test_raffle_enrollment_validation(self): self.client.force_authenticate(user=self.user_profile.user) - response = self.client.post( - reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk}) - ) + response = self.client.post(reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk})) self.assertEqual(response.status_code, 403) @@ -207,9 +188,7 @@ def setUp(self): ) def test_raffle_enrollment(self): self.client.force_authenticate(user=self.user_profile.user) - response = self.client.post( - reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk}) - ) + response = self.client.post(reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk})) self.assertEqual(response.status_code, 200) self.assertEqual(self.raffle.entries.count(), 1) entry: RaffleEntry = self.raffle.entries.first() @@ -217,151 +196,92 @@ def test_raffle_enrollment(self): self.assertEqual(entry.is_winner, False) self.assertEqual(self.raffle.number_of_entries, 1) - @patch('prizetap.models.Raffle.is_claimable', new_callable=PropertyMock) - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("prizetap.models.Raffle.is_claimable", new_callable=PropertyMock) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_not_claimable_raffle_enrollment(self, is_claimable_mock: PropertyMock): is_claimable_mock.return_value = False self.client.force_authenticate(user=self.user_profile.user) - response = self.client.post( - reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk}) - ) + response = self.client.post(reverse("raflle-enrollment", kwargs={"pk": self.raffle.pk})) self.assertEqual(response.status_code, 403) - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_set_raffle_enrollment_tx(self): - entry = RaffleEntry.objects.create( - raffle=self.raffle, - user_profile=self.user_profile - ) + entry = RaffleEntry.objects.create(raffle=self.raffle, user_profile=self.user_profile) self.client.force_authenticate(user=self.user_profile.user) tx_hash = "0xc9f4401d848bf61bd8e225fa800ab259018a917b55b0aa6aa1beefb2747d4af5" - response = self.client.post( - reverse("set-enrollment-tx", kwargs={"pk": entry.pk}), - data={"tx_hash": tx_hash} - ) + response = self.client.post(reverse("set-enrollment-tx", kwargs={"pk": entry.pk}), data={"tx_hash": tx_hash}) self.assertEqual(response.status_code, 200) entry.refresh_from_db() self.assertEqual(entry.tx_hash, tx_hash) - self.assertEqual(response.data['entry']['tx_hash'], tx_hash) + self.assertEqual(response.data["entry"]["tx_hash"], tx_hash) self.assertEqual(self.raffle.number_of_entries, 1) - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_set_not_owned_raffle_enrollment_tx_failure(self): entry = RaffleEntry.objects.create( raffle=self.raffle, user_profile=UserProfile.objects.create( - user=User.objects.create_user( - username="test_2", - password="1234" - ), + user=User.objects.create_user(username="test_2", password="1234"), initial_context_id="test_2", username="test_2", - ) + ), ) self.client.force_authenticate(user=self.user_profile.user) tx_hash = "0xc9f4401d848bf61bd8e225fa800ab259018a917b55b0aa6aa1beefb2747d4af5" - response = self.client.post( - reverse("set-enrollment-tx", kwargs={"pk": entry.pk}), - data={"tx_hash": tx_hash} - ) + response = self.client.post(reverse("set-enrollment-tx", kwargs={"pk": entry.pk}), data={"tx_hash": tx_hash}) self.assertEqual(response.status_code, 403) entry.refresh_from_db() self.assertEqual(entry.tx_hash, None) - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_duplicate_set_raffle_enrollment_tx_failure(self): tx_hash = "0xc9f4401d848bf61bd8e225fa800ab259018a917b55b0aa6aa1beefb2747d4af5" - entry = RaffleEntry.objects.create( - raffle=self.raffle, - user_profile=self.user_profile, - tx_hash=tx_hash - ) + entry = RaffleEntry.objects.create(raffle=self.raffle, user_profile=self.user_profile, tx_hash=tx_hash) self.client.force_authenticate(user=self.user_profile.user) - response = self.client.post( - reverse("set-enrollment-tx", kwargs={"pk": entry.pk}), - data={"tx_hash": tx_hash} - ) + response = self.client.post(reverse("set-enrollment-tx", kwargs={"pk": entry.pk}), data={"tx_hash": tx_hash}) self.assertEqual(response.status_code, 403) - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_set_claiming_prize_tx(self): - entry = RaffleEntry.objects.create( - raffle=self.raffle, - user_profile=self.user_profile, - is_winner=True - ) + entry = RaffleEntry.objects.create(raffle=self.raffle, user_profile=self.user_profile, is_winner=True) self.client.force_authenticate(user=self.user_profile.user) tx_hash = "0xc9f4401d848bf61bd8e225fa800ab259018a917b55b0aa6aa1beefb2747d4af5" response = self.client.post( - reverse("set-claiming-prize-tx", kwargs={"pk": self.raffle.pk}), - data={"tx_hash": tx_hash} + reverse("set-claiming-prize-tx", kwargs={"pk": self.raffle.pk}), data={"tx_hash": tx_hash} ) self.assertEqual(response.status_code, 200) entry.refresh_from_db() self.assertEqual(entry.claiming_prize_tx, tx_hash) - self.assertEqual(response.data['entry']['claiming_prize_tx'], tx_hash) + self.assertEqual(response.data["entry"]["claiming_prize_tx"], tx_hash) - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_set_not_owned_claim_prize_failure(self): - RaffleEntry.objects.create( - raffle=self.raffle, - user_profile=self.user_profile - ) + RaffleEntry.objects.create(raffle=self.raffle, user_profile=self.user_profile) entry = RaffleEntry.objects.create( raffle=self.raffle, user_profile=UserProfile.objects.create( - user=User.objects.create_user( - username="test_2", - password="1234" - ), + user=User.objects.create_user(username="test_2", password="1234"), initial_context_id="test_2", username="test_2", ), - is_winner=True + is_winner=True, ) self.client.force_authenticate(user=self.user_profile.user) tx_hash = "0xc9f4401d848bf61bd8e225fa800ab259018a917b55b0aa6aa1beefb2747d4af5" response = self.client.post( - reverse("set-claiming-prize-tx", kwargs={"pk": self.raffle.pk}), - data={"tx_hash": tx_hash} + reverse("set-claiming-prize-tx", kwargs={"pk": self.raffle.pk}), data={"tx_hash": tx_hash} ) self.assertEqual(response.status_code, 403) entry.refresh_from_db() self.assertEqual(entry.claiming_prize_tx, None) - @patch( - "authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", - lambda a, b, c: (True, None) - ) + @patch("authentication.helpers.BrightIDSoulboundAPIInterface.get_verification_status", lambda a, b, c: (True, None)) def test_duplicate_claiming_prize_tx_failure(self): tx_hash = "0xc9f4401d848bf61bd8e225fa800ab259018a917b55b0aa6aa1beefb2747d4af5" - RaffleEntry.objects.create( - raffle=self.raffle, - user_profile=self.user_profile, - claiming_prize_tx=tx_hash - ) + RaffleEntry.objects.create(raffle=self.raffle, user_profile=self.user_profile, claiming_prize_tx=tx_hash) self.client.force_authenticate(user=self.user_profile.user) response = self.client.post( - reverse("set-claiming-prize-tx", kwargs={"pk": self.raffle.pk}), - data={"tx_hash": tx_hash} + reverse("set-claiming-prize-tx", kwargs={"pk": self.raffle.pk}), data={"tx_hash": tx_hash} ) self.assertEqual(response.status_code, 403) @@ -378,15 +298,15 @@ def setUp(self): native_currency_name="ETH", symbol="ETH", chain_id="1", - max_claim_amount=1e11 + max_claim_amount=1e11, ) def test_unitappass_contraint(self): constraint = NotHaveUnitapPass(self.user_profile) self.assertTrue(constraint.is_observed()) - def test_set_winner(self): - self.raffle.raffleId = 2 - client = PrizetapContractClient(self.raffle) - winner = client.get_raffle_winner() - self.assertEqual(winner, "0x59351584417882EE549eE3B9BF398485ddB5B7E9") + # def test_set_winner(self): + # self.raffle.raffleId = 2 + # client = PrizetapContractClient(self.raffle) + # winner = client.get_raffle_winner() + # self.assertEqual(winner, "0x59351584417882EE549eE3B9BF398485ddB5B7E9") diff --git a/prizetap/utils.py b/prizetap/utils.py index ca0c7bb1..4faa1adb 100644 --- a/prizetap/utils.py +++ b/prizetap/utils.py @@ -1,12 +1,14 @@ +import time + from core.utils import Web3Utils from faucet.models import Chain + from .constants import ( PRIZETAP_ERC20_ABI, PRIZETAP_ERC721_ABI, UNITAP_PASS_ABI, VRF_CLIENT_ABI, VRF_CLIENT_POLYGON_ADDRESS, - LINEA_PRIZETAP_ABI ) @@ -18,40 +20,43 @@ def __init__(self, raffle) -> None: self.set_contract(self.raffle.contract, abi) self.set_account(self.raffle.chain.wallet.private_key) - def draw_raffle(self): - func = self.contract.functions.heldRaffle(self.raffle.raffleId) + def set_raffle_random_words(self, expiration_time, random_words, reqId, muon_sig, gateway_sig): + func = self.contract.functions.setRaffleRandomNumbers( + self.raffle.raffleId, expiration_time, random_words, reqId, muon_sig, gateway_sig + ) return self.contract_txn(func) - def get_raffle_winner(self): + def get_raffle(self): func = self.contract.functions.raffles(self.raffle.raffleId) - raffle = self.contract_call(func) - return raffle[8] - -class LineaPrizetapContractClient(PrizetapContractClient): - def __init__(self, raffle) -> None: - super().__init__(raffle) - abi = LINEA_PRIZETAP_ABI - self.set_contract(self.raffle.contract, abi) + return self.contract_call(func) - def draw_raffle(self, expiration_time, random_words, reqId, muon_sig, gateway_sig): - func = self.contract.functions.drawRaffle( - self.raffle.raffleId, - expiration_time, - random_words, - reqId, - muon_sig, - gateway_sig - ) - return self.contract_txn(func) + def get_last_winner_index(self): + raffle = self.get_raffle() + last_index = raffle[8] if not self.raffle.is_prize_nft else raffle[7] + return last_index + + def set_winners(self): + winners_count = self.raffle.winners_count + last_winner_index = self.get_last_winner_index() + while last_winner_index < winners_count: + to_id = last_winner_index + 25 + if to_id > winners_count: + to_id = winners_count + func = self.contract.functions.setWinners(self.raffle.raffleId, to_id) + last_winner_index = to_id + tx_hash = self.contract_txn(func) + self.wait_for_transaction_receipt(tx_hash) + + return tx_hash def get_raffle_winners(self): - func = self.contract.functions.getWinners(self.raffle.raffleId) + func = self.contract.functions.getWinners(self.raffle.raffleId, 1, self.raffle.winners_count) return self.contract_call(func) def get_raffle_winners_count(self): - func = self.contract.functions.raffles(self.raffle.raffleId) - raffle = self.contract_call(func) - return raffle[6] + func = self.contract.functions.getWinnersCount(self.raffle.raffleId) + return self.contract_call(func) + class VRFClientContractClient(Web3Utils): def __init__(self, chain) -> None: @@ -59,16 +64,32 @@ def __init__(self, chain) -> None: self.set_contract(VRF_CLIENT_POLYGON_ADDRESS, VRF_CLIENT_ABI) self.set_account(chain.wallet.private_key) + def get_last_request_id(self): + func = self.contract.functions.lastRequestId() + return self.contract_call(func) + + def get_last_request(self): + last_id = self.get_last_request_id() + func = self.contract.functions.vrfRequests(last_id) + return self.contract_call(func) + + def get_validity_period(self): + func = self.contract.functions.validityPeriod() + return self.contract_call(func) + def request_random_words(self, num_words): - func = self.contract.functions.requestRandomWords(num_words) - return self.contract_txn(func) + last_request = self.get_last_request() + expiration_time = last_request[0] + now = int(time.time()) + if expiration_time < now: + func = self.contract.functions.requestRandomWords(num_words) + return self.contract_txn(func) class UnitapPassClient(Web3Utils): def __init__(self, chain: Chain) -> None: super().__init__(chain.rpc_url_private, chain.poa) - self.set_contract( - "0x23826Fd930916718a98A21FF170088FBb4C30803", UNITAP_PASS_ABI) + self.set_contract("0x23826Fd930916718a98A21FF170088FBb4C30803", UNITAP_PASS_ABI) def is_holder(self, address: str): func = self.contract.functions.balanceOf(address)